• ベストアンサー

大容量の静的な確保の限界値

char buf[1234567890]; 静的な確保では限界があって、大きい容量を確保するならnewを使うけど、静的な確保が保証されているのはどれぐらいですか? 個別の変数でなく、アプリケーション全体で、アプリケーションの起動時に確保できる容量が決まっていると思うんだけど、Windows上で他のアプリケーションがたくさん起動していたりすると、静的確保の限界値も変わってくるんでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • nitscape
  • ベストアンサー率30% (275/909)
回答No.3

Visual C++ Ver6.0 SP5、WindowsMe、640MBの環境でWizardによってダイアログベースのアプリを作成して全てデフォルトのまま以下の変数を定義したところ... static BYTE lpBuff[1000000000]; 下のような警告が出ました。 warning LNK4084: トータル イメージ サイズ 1028317184 が最大値 (268435456) を越えています; イメージは動作しない可能性があります また、 TRY { BYTE* lpBuff; lpBuff = new BYTE[640000000]; delete lpBuff; } CATCH_ALL(e) AfxMessageBox("error"); END_CATCH_ALL ようにしたところコンパイルはできるものの例外がトラップできました。

A__
質問者

お礼

ありがとうございます。 最大値 (268435456) というのは何かよく分からないけど、大きいですね。 俺は、http://www.mediawars.ne.jp/~freemage/progs/win01.htm のスケルトンの、case WM_PAINT:を消して、switch(uMsg)の前に、char buf[250000];を書いて、エラーはありませんでした。 char buf[250000];エラー無し char buf[260000];終了時にエラー char buf[600000];起動時にエラー でした。 1つの変数でなく、アプリケーション総合に限界があるみたいです。 char buf[120000];とchar buf2[130000];エラー無し char buf[130000];とchar buf2[130000];終了時にエラー でした。 終了時にエラーというのはとてもやっかいだと感じました。そんなことが起きると、case WM_DESTROY:のソースのデバッグを始めてしまいそうです。 char buf[250000];でエラーが起きることがあったり、 char buf[260000];でエラーにならなかったりしたらお知らせください。

その他の回答 (4)

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.5

自分に突っ込み! > newによる動的領域確保は実装方法が不明確(処理系ごとに違う可能性がある)ので、APIでの動的猟奇確保<<誤字>>を利用するべきです。 おかしい事言ってますね。 newによる動的領域確保は実装方法が不明確(処理系ごとに違う可能性がある)ので、「『大容量の領域』または『長期間維持する領域』の場合は」APIでの動的領域確保を利用するべきです。 と書くべきでした。 じゃ、「大容量って何バイトから?」、「長期間ってどれくらい?」という話になるのですが… 時と場合と環境で決まります。 OSによっては「大容量領域確保用のAPI」や「メモリフラグメンテーションを回避するためのAPI」が用意されていることが多いので、言語処理系付属のプログラミングマニュアルやOSのアーキテクチャ解説書を参照して利用するAPIを決定します。

A__
質問者

お礼

動的確保はnewしか知らないんだけど、もっと安定したAPIがあるということですね。 ありがとうございました。

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.4

2の28乗バイトの静的データを必要とするEXEファイルは起動できません(Windowsの場合限定)。 これは明確な限界値が存在するので問題となることは少ないでしょう。 実行エラー(起動時、実行中、終了時)のエラーに関しては環境依存です。 ・実装メモリ ・仮想記憶設定 ・ページファイルを保持するディスクドライブの残り容量 ・同時実行されているソフトウェアが占有するページ仮想記憶容量 などです。 通常、メモリ確保時のエラー報告を受け取りやすい動的領域の利用が推奨されます。 newによる動的領域確保は実装方法が不明確(処理系ごとに違う可能性がある)ので、APIでの動的猟奇確保を利用するべきです。

A__
質問者

お礼

ありがとうございます。2の28乗という制限があるのは知りませんでした。 char buf[600000];の時の、600000*256=153600000で起動できなかったけど、 2の28乗の268435456までは100000000バイトあります。 この場合は2の28乗の制限よりも、環境依存の実行エラーの条件にあてはまったみたいですね。

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.2

ずっと昔し、スモールモデル、ラージモデル。。。 などの区別があって、ポインターのビット数やデータ領域の大きさなどの 話がありました。その頃はそれぞれのモデルでの限界値がはっきり決まっていました。  これについては、16ビットの頃のコンパイラのマニュアルを見れば良いと思います。  その後、ウインドウズのメモリーの扱いが変化してきて、 本当のメモリーの上に確保できないときは勝手にハードディスクの上の 移してしまうようになりました。  従って、外部変数として静的に確保するのはかなり大きなものでも大丈夫だとおもっています。確保の時の状態としては、ハードディスクが回転しっぱなしの状態になる。  内部変数は、話が別です。 あまり大きな領域を確保すると、ソフトウエアの性能が落ちると思います。 理由は、ハードディスクとのやりとりが始まると時間がかかりすぎるから。 メモリーは、必要なときに必要なだけ確保し、ポインターをチェックして ほんとに確保できたか判定してから使い、いらなくなったらすぐに解放する。 このようにしないと、メモリーの少ない機械に移して稼働させるときに 使いものにならないプログラムになると思います。 最近、マイクロソフトのビジュアルスタジオのマニュアルを読んだのですが 詳しい話は書いてなかったです。 間違った内容の記述かもしれませんので、 他の専門家の方々の意見も聞かせていただければ幸いです。

A__
質問者

お礼

ありがとうございます。 心配なぐらい大きいならnewして、newからのエラーを受けるのが確実だけど、どれぐらいからが心配なのかさえ分からない状態なんです。

  • nitscape
  • ベストアンサー率30% (275/909)
回答No.1

コンパイルするときにラージにするとかスモールにするなどで変わるのではないでしょうか? プログラムの動作時のメモリ確保はnewでも静的でも失敗することはあると思います。

関連するQ&A