0

Java と C# から来て、私は次のことを行うことに慣れています。

byte[] myArray = new byte[10];

クリーンアップする必要はありません。ただし、C++ を使用するようになったので、割り当てとメモリ リークに注意する必要があることは明らかです。

動的割り当ては絶対に避けるべきだと言う人もいますがnew、ローカル スタック変数で十分な場合に演算子を使用してクラスをインスタンス化して、それを「自由に」使用する人もいます。

DatabaseConnection conn = new DatabaseConnection("127.0.0.1");
// or
DatabaseConnection conn("127.0.0.1");

ヒープに割り当てられた配列がはるかに遅いことは承知していますが、動的メモリを使用した結果として発生する可能性のある小さなパフォーマンス ヒットよりも、読みやすく拡張可能なコードを優先します。

ですから、私の質問は次のとおりです。ヒープの割り当てを絶対に避けるべきだというのは本当ですか?

4

5 に答える 5

5

この場合、これを使用しても問題ないことをお勧めします。

byte myArray[10]; 

コピーできる配列が必要な場合 (関数からの戻り値など)、使用するvector<byte>のが正しい解決策です。

最後の手段は を使用しnew、データが関数の外に存在する必要がある場合にのみ小さな領域を割り当てることです。

new残念なことに、本は常に良い実践方法を教えてくれるわけではなく、使用すべき場合と使用すべきでない場合の良い例を示しているわけではありませんint *arr = new int[5];

もちろん、すべてnewが である必要がありますdeleted。スマート ポインター (shared_ptrまたはunique_ptr) を使用すると、自動クリーンアップが行われるため、非常に役立ちます。

于 2013-08-08T17:42:26.360 に答える
3

いつでも可能なとき?はい。どうしても?いいえ。動的割り当ては、多くの場合、問題に対する最も簡単な解決策です。

ただし、事実上すべてのコストをかけて使用することは避けてください。new信頼しmake_sharedmake_unique単一のオブジェクトを生成し、コンテナstd::vectorを複数のように生成します。を使用する言い訳はありませんdelete

于 2013-08-08T17:45:44.663 に答える
1

はい、本当です。可能な限りヒープ割り当てを避ける必要があります。あなたが言及した場合std::vector<byte>、コメントで提案されているように、標準ライブラリによって提供されるコンテナを使用する必要があります。

どうしてもヒープに何かを格納する必要がある場合は、RAII (Resource Acquisition Is Initialization) を使用します。これは、構築時に取得を実行し、破棄時にリソースを解放する (スタック上の) オブジェクトを意味します。C++11以降、リソースの複数の所有者が必要な場合はstd::unique_ptr、これ、またはより洗練されたstd::shared_ptr(と一緒に)があります:std::weak_ptr

std::unique_ptr<int> unique(new int(42));
auto sp = std::make_shared<int>(42);

C++11 をまだ使用できない場合、ほぼすべてのライブラリが何らかのスマートポインターを提供します。ブーストにより、scoped_ptr/ scoped_arrayshared_ptr/ shared_arrayweak_ptr、およびintrusive_ptr; Poco はAutoPtrなどを提供します。C++03 にはスマートポインターもありますがauto_ptr、それを使用しないことを強くお勧めします。C++03 は右辺値参照 / 移動セマンティクスをサポートしていないため、その使用は非推奨になり、本当に奇妙なコピー動作をします。

于 2013-08-08T17:41:57.343 に答える
1

このような質問には、常に 2 つのベクトルからアプローチできます。保守性/可読性とパフォーマンス。2 番目が重要な場合もあれば、そうでない場合もあります。最初は気にしないこともあります。ただし、この場合、自動メモリ (「スタック」) と動的メモリ (「ヒープ」) に可能な限り多くのものを配置すると、両方の点で (ほとんどの場合) 勝つと言えます。

動的メモリの割り当ては、スタック ポインターの変更に比べて非常に遅いため、パフォーマンスに関する議論はほとんどありません。しかし、動的メモリのスコープを離れないものを割り当てる場合は、スコープの後にメモリを解放するように注意する必要があります。忘れると、メモリをリークするだけでなく、デストラクタがそうではないため、正確性が損なわれる可能性がありますと呼ばれる。その点で、保守性は低くなります。

すべてに懐疑的newで、臭いと考えるのに役立ちます. 不必要にやりすぎるのを防いでくれます。

于 2013-08-08T17:43:06.820 に答える
0

動的割り当てに関するいくつかの問題:

  1. メモリ リーク (オブジェクトの削除を忘れた場合)
  2. 多数の割り当て/解放要求 - 一方、スタック割り当ては、関数が呼び出されたときにスタック ポインターを 1 回移動するだけです。一部の自動変数は、メモリを使用せずにレジスタに常駐することさえあります。
  3. ヒープの断片化。

基本的に、他のすべてのオプションを使い果たした場合にのみヒープを使用してください。

于 2013-08-08T17:43:37.207 に答える