プレイ日記
みなつ tksm372
すみません、公開キーを間違っていたので再投稿です。 CHR$()でOut of memoryになった記憶があったので、再現できるプログラムを作りました。 公開キー【22VNN3L4】 STR_MEMORY_TEST 3号でもBIGでも、5行目のCHR$()でOut of memoryになります。 ただ、追試して分かったのですが、CHR$()じゃなくて、単に5行目を C$="1" とかにしても同じくこの行でエラーになるようでした。 また、3号だと残りメモリが250KBなので、まぁそんなものかなとも思うのですが、BIGだと残り110MBもあるのに、Out of memoryになります(もちろん、3号で実行した場合に比べてループがもっと進んでからですが)
14そうだね
プレイ済み
返信[1]
親投稿
みなつ tksm372
実行結果はこんな感じで、5行目の C$=CHR$(1) でOut of memoryになります。
0そうだね
プレイ済み
返信[2]
親投稿
ツララ LongIceSword
文字列は配列みたく扱えて A$="ABCDEF":?A$[4]でEが表示されるみたいな使い方出来ますから 5行目の文字列変数に代入してる処理で配列を宣言して 8行目の文字列配列に代入してる処理で配列の次元を増やしてるみたいなことになってたりするんじゃないです?
2そうだね
プレイ済み
返信[3]
親投稿
みなつ tksm372
おっしゃる通り、おそらくプチコンの文字列は配列、というかポインタで、文字列配列のほうはポインタの配列だと思います。 簡単のため5行目がC$="文字列"だとして、Cで書くと char *A[100000]; ←ポインタの配列 for(i=0;i<100000;i++) { char *c=malloc(strlen("文字列")+1);strcpy(c,"文字列"); // 5行目 A[i]=c; // 8行目 } 多分、こんな感じですよねー。 8行目はアドレスを代入してるだけで、メモリが確保されるのは5行目のmalloc()だけだから、Out of memoryが出るのが5行目というのはもっともです。 なので、問題は5行目に相当する「文字列用のメモリの確保」の実装にあるんじゃないかなーと思ってます m9(`・ω・´)
1そうだね
プレイ済み
返信[4]
親投稿
ツララ LongIceSword
ということは文字列配列に実際に文字列を代入して使う時は、DIM命令で宣言した時の添字の個数全部を使うとすると、最大で倍のメモリ量を使うってことなんです? もしかして文字列配列を使う処理をする時は出来るだけDEFの中で使う様にして、処理が終わったら常時メモリを開放するようにした方がいいとか・・・? ダイレクトモードじゃないとCLEAR命令使えないですし。 というか仕組みが分かってるなら、何でセットでエラーの回避方法も考えないんです?
1そうだね
プレイ済み
返信[5]
親投稿
Godot orz_127
気になったので試してみたら…。 文字配列に""(空文字列)を代入しても "0"*116を代入しても同じ結果で 一度に4096確保して15回代入すると また確保。 "0"*117としたら毎回272単位でメモリを消費。 後ろの乗数を大きく変えると変化しますが"0"*118だと同じ結果。 ちょっと謎。
2そうだね
プレイ済み
返信[6]
親投稿
文字列が生成されたとき("1"やCHR$(1)のほう)に文字列確保用ヒープメモリに固定バイト(文字列連結の拡張用)で文字列領域が生成されて、ポインタ配列に参照があるからGC(garbage collection)されずにヒープだけが枯渇してるように見える感じなのかなー 公式ファンミーティングで内部設計公開してたらしいけど、実際のところどうかなー
2そうだね
プレイ済み
返信[7]
親投稿
みなつ tksm372
Godotさん、興味深い調査結果ですね! 空文字でも116文字でも同じメモリ消費ということは、たんじぇさんも指摘されてますが、連結とかを考えて結構スキマをあけてブロック単位でメモリを確保してそうですねー。 ちなみに、私もたんじぇさんの言う通り、文字列専用のヒープが別にあるのかなーとも思ったのですが、単に文字列に1文字INCし続けるだけだと、メモリの限界まで使えたような気もします。 C$="1" FOR ...:INC A$,C$:NEXT みたいな・・・ 今手元にプチコンが無いので、後で確かめてみたいと思います(≧∇≦)b
1そうだね
プレイ済み
返信[8]
親投稿
とりあえずメモリがたくさんあると言われるBIGでは何回目のループでエラーになるのかが気になりますね〜
0そうだね
プレイ済み
返信[9]
親投稿
みなつ tksm372
でんぺんさん、私の日記にBIGでの実行結果を貼っておきました! ループ回数64985回、残りメモリ110.77MB(BIGの使用可能メモリは128MBです)の時点でエラーが出てましたー@@; 残りメモリいっぱいあるのににゃー(´・ω・`)
0そうだね
プレイ済み
返信[10]
親投稿
Godot orz_127
何か前のコメントのプログラムで DIM A$[100000]のサイズが400040。 ポインタって4バイトか?と。 試してみた。 もしかして8バイトバウンダリ? 調査が別な方向にw
0そうだね
プレイ済み
返信[11]
親投稿
Godot orz_127
あ、画像忘れた。 8バイト毎に増えている。 1要素も2要素も8バイト。
0そうだね
プレイ済み
返信[12]
親投稿
みなつ tksm372
2要素で8バイトということは、一応、アドレス1つは4バイト(32bit)のようですね^^; でも、1要素でも変わらないということは、おっしゃる通り、8バイトバウンダリがあるんですかねー^^; メモリにアクセスするとき、64bit(8バイト)ずつアクセスしてるとか@@;
0そうだね
プレイ済み
返信[13]
親投稿
みなつ tksm372
あと、1文字ずつINCして、どこまで文字列が伸びるのか試してみました! 3号だと、FREEMEMが残り25,272バイトになるまでは伸びるようです。 BIGでもやってみましたが、こちらは残り16,777,560バイト残したところでOut of memoryでした。うーん、16MBも残ってるのにぃ、けちぃ(←そういう問題じゃない…
0そうだね
プレイ済み
返信[14]
親投稿
みなつ tksm372
一応、実行結果も貼っておきますね。
0そうだね
プレイ済み