大きな添え字の配列を作るには?

解決


画像くん  2008-11-26 08:58:10  No: 32706

こんばんは、いつもお世話になっております。
プログラム作成中このような配列の宣言をしました。

>C, K, E : array[0..65535] of integer;

これはうまく動作し、思い通りの結果が出力されました。
長くなるのでここでは動作内容については触れません、すいません。
次に添え字を65535の2倍の131070にしてみました。

>C, K, E : array[0..131070] of integer;

すると、今まで正常に動作していたプログラムが動かなくなってしまいました。
(コンパイルは通ります。実行もできます。)
宣言文だけを変更し、65536以降の配列にはアクセスしていません。
ちんぷんかんぷんで、お手上げなのですがこれ以上の配列を使ってデータ処理を行いたい場合、どのような手段が考えられますでしょうか。
あいまいな質問で申し訳ありません。
関係ないかもしれませんが、Delphi Personal6 WindowsXP 32bit環境です。


ウォレス  2008-11-26 19:01:58  No: 32707

C :array of Integer;

として、

SetLength(C ,65536*2);

ならどうでしょうか?


宣言場所は?  2008-11-26 19:13:27  No: 32708

実行できるのに「動かなくなってしまいました」とは如何に?
もしローカルでそんな大きな配列を宣言すると、スタックが破綻するよ。


Manbon  2008-11-26 20:19:07  No: 32709

質問者じゃないですけど・・・
おお!!知りませんでした!!
以下のようにすれば問題ないですね。
(でもなんで??)

  private
    { Private 宣言 }
    C, K, E : array[0..131070] of integer;


画像くん  2008-11-26 21:37:11  No: 32710

動的確保と、プライベート宣言ですね。
やってみます。

32bitOSなので2Gの壁かと一瞬思ったりもしました。
ちなみに129000だと動作します。

出先なので確認でき次第、書き込ませていただきます。
いつもながら、お力添え感謝します。


  2008-11-27 08:36:31  No: 32711

配列ってメモリ領域を連続で確保してるんでしたっけ?
だったら連続した領域を確保できないためにエラーが出ているのかもしれませんが。


画像くん  2008-11-29 05:06:52  No: 32712

時間が空いてしまい、申し訳ありませんでした。
確認できたので書き込ませていただきます。
結果から言いますと、ウォレスさんの方法でうまくいきました。
未だに、うまく動作しなかった理由はわかりません。

>C :array of Integer;
>
>として、
>
>SetLength(C ,65536*2);

これらの配列に格納したデータをテキストに書き出す処理をループ(30程度)でしているため、処理が重いです。
実はもうすこし大きな配列がほしいのですが、配列を増やすのはここまでにしておきます。
また、何かアイデアがありましたらレスつけていただけたら幸いです。

ご教授ありがとうございました。


ウォレス  2008-11-29 06:02:15  No: 32713

Windowsでは性的な猟奇もとい静的な領域に大きなメモリを確保することはできないらしいです。
大きなメモリはヒープ領域に確保しないとイケマセン。
WinXPだと1.5GBくらいなら問題なく確保できますよ(勿論残っていればですが)。


結局宣言場所はどこ?  2008-11-29 06:06:37  No: 32714

> 未だに、うまく動作しなかった理由はわかりません。
理由については「宣言場所は?」さんが言及していると思いますが……キーワードは「スタック」です。

ローカル変数はその関数の中でだけ存在して、関数を抜けると消えますよね?
このような変数は一般に「スタック」と呼ばれる場所に作られます。
スタックは確保・解放にコストがかからないかわり容量が限られており、
食い潰してしまうといわゆるスタックオーバーフローを起こします。
ちなみにInteger=32bitとして、131,070要素の配列を3つ作ったら約1.5M。スタックにはけっこうきびしいですね。

一方、オブジェクトのフィールドや動的配列などは「ヒープ」から確保されます。
ヒープからの動的なメモリ確保・解放にはコストがかかりますが、
その分大きなメモリでも確保することができます。

大きなメモリを扱うときには、どこに領域が確保されるかを意識しなくてはいけないと覚えておいてください。
ヘルプで「変数」や「メモリ管理」をひいてみればその辺の話が出てくると思いますよ。

まあ、サイズの決まっている配列なら、動的配列にするよりも
関数の外でグローバル変数として用意した方が手っ取り早いかもしれません。


画像くん  2008-11-29 08:05:46  No: 32715

ほ、本当ですね!
グローバルに宣言すると、まだまだイケました〜。
悩んでいたことが、パッと晴れました。
スタックとヒープについても勉強になりました。
皆さん、お手数おかけしました〜。


Mr.XRAY  2008-12-06 04:47:16  No: 32716

>スタックは確保・解放にコストがかからないかわり容量が限られており、

少なくともDelphi7,2007のデフォルトは$100000のようです.
(10進数だと.え〜と.1048576バイトですか)


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加