2011-02-04 10 views
1

C++のソースコードをいくつか変更していますが、著者が実際にスタック上のすべてのものを割り当てていないことに気付きました。ほとんどの場合、割り当て解除のメリットがあります(パフォーマンス上のメリットもありますか?)。私は同じ一貫性を維持したいが、私は、オブジェクトとのようなものの大規模な配列を作成する必要がありスタック上の大きなオブジェクト配列のコンストラクタを呼び出す

Object os[1000] = {Object(arg), Object(arg), ....}; 

はそれをカットするつもりはありません。その周りに検索すると、この回避する方法のように思えるだけです:

vector<Object> os(1000, Object(arg)); 

これはまだヒープに割り当てますが、(私は他の記事で読んだから)スタックのように割り当てを解除します。これは構文上の問題のように思えるので、他にもオプションがあるのだろうかと思っています。多分賢明な#define人々は知っている。

+0

これは主に冗談ですが、真実の要素を持っています...オプションがあります:ポインタと参照とデザインを使用してメモリ管理が問題にならないようにする方法を学びます。 –

+0

パフォーマンス上の利点:スタック割り当ては常に* O(1)です。ヒープ割り当ては非決定的です。 – Mehrdad

+1

@Mehrdad:無限のスタックを持つ理想的なコンピュータで作業しているなら、常に* O *(1)です。現実の世界では、最終的に現在のスタック制限を超えて割り当てることになり、OSはあなたにもっと多くのメモリを割り当てる必要があります。最悪の場合、使用可能なスタック領域が使い果たされ、プロセスが進行します。 –

答えて

1

スタックは、大きなメモリブロックに使用しないでください。より多くのメモリにアクセスする利点の代わりに、ヒープ割り当ての高い価格を支払うだけで済みます。もう1つのオプションは、静的な記憶期間を持つ配列を宣言することですが、それには他の欠点があります(スレッドセーフではなく、リエントラントではありません)。すべてがトレードオフです。

いずれにしても、複雑なオブジェクトを割り当てる場合、1000コンストラクタを呼び出すコストは、アロケータで費やされる時間を犠牲にします。パフォーマンスの問題を示すプロファイラデータがない限り、std::vectorを使用してください。

0

大量のデータをスタックに割り当てることは、一般的に悪い考えです。ほとんどのオペレーティングシステムのスタックは、スクラッチスペースであり、サイズはかなり制限されています。大量のスタック領域をオブジェクトに割り当てると、使用可能なスタック領域がすべて消費され、スタック上にもう1つのもの(関数呼び出しの戻りアドレスなど)を割り当てようとすると、segfaultやその他の例外が発生する可能性があります。

他のオプションとしては、既に気づいているように、いくつかのstd :: vectorがあります。boost :: arrayはそのような例です。

1

はい、他にもオプションがあります。 allocaのようなものを使うことができます。これによりスタックの割り当てと自動的な空きができますが、自動構築や破棄はできません。デストラクタの新しく明示的な呼び出しを使用する必要があります。

はい、パフォーマンスの優位性があるかもしれませんが、スタックを吹き飛ばすこともあります。このパターンは、vectorソリューションのように例外的なものではありません(つまり、些細なデストラクタ)。

0

これが機能するべき:

Object os[1000]; 
os[0] = Object(args); 
std::copy(os, os + 999, os + 1); 

これは、配列を作成し、一つのオブジェクトを初期化し、その後、最後の各要素を初期化する、をループ。

もちろん、これを使用しないでください。それは動作しても悪い考えのように思え、たとえObject os[1000]が問題を引き起こさない場合でも。

関連する問題