2011-01-31 5 views
2

非常に大きな配列を作成する必要があります。 50メガバイトと言いましょう。ヒープ上に静的配列を作成しますか?

通常の静的配列として安全に作成できますか?コンパイラはスタックにスタックを置くか(スタックのオーバーフローを引き起こす可能性があります)、ヒープ上に置くほどスマートになりますか?

もしそうでない場合は、mallocで簡単に実行できますか?またはプログラムが起動すると「new」が簡単に終了しますが、プログラムが終了すると自動的に解放されますか?

+4

staticのキーワードのように 'static'を意味しますか? 'not dynamic'のように意味しますか? – James

+0

キーワードは静的です。私はこれも動的ではないことを意味すると思います! – Pubby

答えて

3

私が理解しているように、静的変数はスタックには存在しません。彼らが行った場合、彼らは彼らが住んでいるスタックフレームをポップするときにどこに行くのだろうか?静的関数変数は呼び出し間で状態を保持する必要があるため、論理的には静的データをヒープ上に保持する必要があります。

また、プログラムが終了すると、すべてが自動的に割り当て解除されます。

+0

ああ、私は彼らがスタックしていないだろうと思う。 – Pubby

+0

すべてがスタック上で自動的に割り当て解除され、ヒープ上では割り当て解除されません。 –

+0

プロセスのために割り当てられたメモリ内にはありませんか?プログラムが終了すると、それはOSに戻されます。 – Twisol

2

これを行う簡単な方法は、STDを使用している::ベクトル

std::vector data; 
data.reserve(<Number of Elements); 

または潜在的にはstd ::両端キュー(使用状況により異なります)。

コンパイラはスタックにスタックを置くか(スタックオーバーフローの可能性があります)、それともヒープに配置するのに十分なスマートなのでしょうか?

スタックオーバーフローは、理論的スタックと理論的ヒープが衝突して混在するときです。スタックがオーバーフォーになると、ヒープも失敗するでしょう。

システムの中には、スタックフレームの最大サイズ(これはコンパイラとプラットフォーム固有)があります。詳細は、コンパイラのドキュメントを参照してください。その結果、大規模な構造を動的に(直接ではありませんが)割り当てるのが通常です。

std :: vectorはこれを(おそらく)行います。小さなローカルオブジェクトが存在しますが、メインのペイロード(通常)は動的ヒープ割り当てとして実装されています。

+0

私はstd :: vectorを使いたくありません。私はデストラクタを利用してクラスでラップすることができると思います。 – Pubby

+1

@ペペ:どうしてですか? –

+3

私は配列について尋ねたので。 – Pubby

0

50メガバイトは今日の基準ではそれほど多くはありません。

C++ new演算子を使用してプログラムの先頭に割り当てることができ、最後にdelete [](または定義されたプログラムセクションの開始/終了)で割り当てを解除できます。

この配列が、たとえば読み込まれるファイルの一部を表している場合は、ファイルがメモリに読み込まれたときにそれを割り当てることをお勧めします。最適な方法として、ファイルのセクションのみをメモリにマップすることができます(たとえば、1MB、2MB、または使用する別の論理ユニット)(WindowsではMapViewOfFile、UNIXシステムではmmapを参照してください)。この方法では、仮想メモリを使い果たすことなく非常に大きなファイルを読み込むことができます。

+0

手動で 'new'と' delete'を呼び出すことは、Leakapaloozaへのチケットです。 – fredoverflow

+1

もし私がリパパルアザへのチケットを望んでいなかったら、私はベビーjavaのコードを書いていたでしょう! – Pubby

+0

@FredOverflow:.NETまたはJavaでC++ 2)プログラムが必要な場合は、リソース(RIAA)を注意深く追跡できます。 –

1

静的に割り当てると、静的に割り当てられます。典型的な場合、実行可能ファイルには、特定の変数がゼロ初期化されたサイズNのブロックであることを指定するレコードがあります。ローダーは通常、プログラムのコードのためのスペースを割り当てるのと同じように、そのような場合(例えば、アドレス空間を割り当てますが、実際にはそのメモリを読み書きしない限り、は実際には実際のメモリではありません)。

2

私の経験上、このような大きな配列をヒープ上に割り当てることが良い(新しいものから) - スタック上に2 MBを割り当てた後、UNIXシステムでプログラムのコアダンプを見た... 自動削除が必要な場合は、スマートポインタ(boost :: scoped_arrayなど)を使用できます。しかし、「プログラムが終了したら自動的に削除する」と言いますから、実際に何もする必要はありません。オペレーティングシステムは、終了時にすべてのプロセスのメモリを再利用します。

とにかく、実際には、生の配列の代わりにstd :: vectorを使用する必要があります。

関連する問題