web-dev-qa-db-ja.com

とにかくプログラムが終了しているときにC ++でdeleteを呼び出す理由はありますか?

たとえば、C++ main関数で、(スタックメモリではなく)ヒープメモリを使用する変数へのポインタがある場合、これはアプリケーションの終了後に自動的に割り当て解除されますか?私はそう思います。

それでも、メモリが終了時に自動的に割り当て解除される状況ではヒープ割り当てが使用されないと思われる場合でも、ヒープ割り当てを常に削除することをお勧めしますか?

たとえば、これを行うことに意味はありますか?

int main(...)
{
    A* a = new A();
    a->DoSomething();
    delete a;
    return 0;
}

そのコードをリファクタリング(または他の誰かがリファクタリング)してアプリケーションの他の場所に配置する場合に備えて、多分と考えていました。ここで、deleteは本当に必要です。

Brian R. Bondyによる回答(C++での影響について具体的に説明しています)に加えて、Paul Tomblinには C固有の質問に対する適切な回答 もあります。

44
Nick Bolton

実行したいコードがデストラクタにある可能性があるため、明示的にdeleteを呼び出すことが重要です。たぶん、ログファイルにデータを書き込むようなものです。 OSにメモリを解放させると、デストラクタのコードは実行されません。

ほとんどのオペレーティングシステムは、プログラムの終了時にメモリの割り当てを解除します。ただし、自分で割り当てを解除することをお勧めします。前述のように、OSはデストラクタを呼び出しません。

一般にdeleteを呼び出す場合は、常にdeleteを呼び出す必要があります。そうしないと、プログラムでメモリリークが発生し、新しい割り当てが失敗します。

69
Brian R. Bondy

はい。メモリリーク検出ツールを使用してプログラムを実行するときに、誤検知を排除するのに役立ちます。

25
Ferruccio

はい。

  • 標準では、OSがメモリをクリーンアップすることはありません保証。これは主流のプラットフォームで期待できますが、なぜチャンスをつかむのですか?
  • 意図的にメモリをリークしない場合は、valgrindなどのツールによって報告される混乱を最小限に抑えます。
  • この習慣を身に付けた場合、いつの日か誤ってこのアプローチを重要な場所に適用することはないと誰が言いますか?
  • あなたmayオブジェクトの破壊が必要です。通常はあなたがそうすると仮定します。それはあなたを傷つけません。

削除するオブジェクトが、OSで安全に解放できない外部リソースを取得した場合を考えてみます。そのオブジェクトに対してdeleteを呼び出さないと、実際にリークが発生します。

7
Sebastian Mach

クラスAを破壊しなければならないことを考えてください。
deleteaを呼び出さない場合、そのデストラクタは呼び出されません。通常、プロセスがとにかく終了しても、それは実際には問題ではありません。しかし、デストラクタがリリースする必要がある場合はどうなりますか?データベース内のオブジェクト?キャッシュをログファイルにフラッシュしますか?メモリキャッシュをディスクに書き戻しますか?

ご覧のとおり、オブジェクトを削除することは単なる「グッドプラクティス」ではなく、状況によっては必要になります。

6
Stefan

オブジェクトを明示的に削除するもう1つの理由は、アプリケーションに実際のメモリリークがある場合、発生する「リーク」をふるいにかける必要がなければ、 valgrind などのツールを使用してリークを見つけるのが簡単になることです。わざわざ片付けないことから。

4
Mr Fooz

削除するもう1つの理由は、将来使用する可能性のあるリークディテクタからの誤警報を回避するためです。誤警報がある場合は、リークディテクタによって報告された実際のリークに注意を払わない可能性があります。レポートの誤警報の中に埋もれてしまいます。

4

必ず自分で削除してください。 OSがこれを処理しますが、簡単に回避できるバグを除外します

2
RvdK