2011-12-21 8 views
10

私はいくつかの "グローバル"構造を持っています。これらの構造は、新しいもので割り当てられ、アプリケーションの寿命の全体にわたって生きています。C++では、アプリケーションのライフタイム変数へのポインタを削除する必要がありますか?

アプリケーションが終了する直前にポインタの削除を呼び出す必要がありますか? とにかく閉じた後、アプリケーションメモリのすべてが再利用されるわけではありませんか?

Edit For Clarity。私は、プログラムが終了すると直ちに "死ぬ"生涯オブジェクトの削除を呼び出さないことについて話しています。

+0

グローバル変数をポインタからスマートポインタに変更してみませんか?あなたはまだ破壊の問題にぶつかることはありませんが、ごくまれにしか起こりません。最初の場所に設定する方法に少し依存します - スマートポインタがヌルとして始まり、後で割り当てられる場合、正しいコン/破壊順序を追跡するのは通常は難しい)ポインタは、割り当てられたオブジェクトで初期化されます。 –

答えて

0

いいえ、OSがすでに非常に優れていることを行うためのコードを作成/デバッグ/維持しないでください。

具体的な理由がない限り(例えば未処理トランザクションをコミットする、ファイルをフラッシュする、接続をクローズするなど)、OSがとにかく何かをするためのコードを書いても構いません。dtorが何も特別なことをしない場合、なぜそれを呼ぶのをやっているのですか?

多くの開発者は、アプリケーションの終了時に、アプリケーションをシャットダウン/フリーズ/終了するために多くの努力を払っています。破壊される。

1)それが終了しようとするため、デストラクタが正常に動作しない場合:

+7

これは信じられないほどです。 0アップフォートの答えは、9アップフォートの[正解]よりもどのように選択されましたか?問題は、マーティン、あなたのアプローチでは、あまりにも多くの知識が必要であるということです。つまり、デストラクタが「何か特別なことをする」かどうかを個々のケースごとに*知る必要があります。コードを正しく書くという習慣に入る方がずっといいですし、デストラクタがどのように書かれているかは関係ありません。デストラクタが何をしているのか知る方法がないところでライブラリコードを呼び出す場合は、特に*真です。 –

+4

一般的な教訓は、コードを書くのが簡単ではないということです。 –

+2

"偽の"リークレポートを整理整頓していない場合、どのリークレポートが "偽"ではないのか、どのように把握していますか? –

26

技術的には、メモリが再利用されます。しかし、deleteを使用しない限り、それらのオブジェクトのデストラクタは実行されず、その副作用は適用されません。これにより、一時的なファイルが削除されないか、またはデストラクタの目的に応じてデータベースの変更がコミットされないことがあります。

また、Murphyも忘れないでください。これらのオブジェクトを管理するためのコードは、あなたが記述したとおりに使用されます(オブジェクトはプログラムの存続期間中存続する必要があります)。後で複数回実行するようにコードを再利用することができます。オブジェクトを適切に再作成することができない限り、オブジェクトが漏れてしまいます。

+0

+1デストラクタを考慮してください。 – AusCBloke

+1

マーフィーはここで両方向で働いています。削除しないと、オブジェクトのいくつかがデストラクタで重要な動作をしていることを確認できます。削除を行うと、そのオブジェクトがある静的オブジェクトのデストラクタで使用されていることを確認することができ、破棄の問題の順序で実行します。 –

+0

+1です。もちろん、あなたが間違いなくdtorsが呼ばれることを望まない場合があります。彼らが図書館で立ち往生し、ブロックされたスレッドが終了するのを永遠に待っているような愚かなことをするとき。 –

1

あなたはおそらく正しいと思いますが、私は個人的にはシステムに頼るのが貧弱なコーディングと悪い習慣と考えていて、自分のコードがいつも正しくシャットダウンするようにしています。

+0

あなたのOSは信頼できませんか?すでにカバーされている作業に時間を費やすのは無駄です。つまり、「きれいにシャットダウン」しようとするアプリケーションは、しばしばシャットダウンしない傾向があります。実際には、OSに終了を要求するアプリケーションよりも信頼性が低いです。 –

+0

@マーティン・ジェイムズ:私は繰り返し仕事にあなたのポイントを取る、しかし、私はあなたの議論は本当に問題の原因になる最終的に習慣、かすかなショートカットのための言い訳だと思う。いいえ、私は絶対にOSを信用しません、あなたはOSがすべてのものを正しく扱うことは想定できません、あなたのコードがそれに当てはまるかもしれない既存のまたは将来の順列あなたはそれが意図している通りにすべてがうまくいくとは思っていません。絶対に確実な唯一の方法は、あなた自身ですべてを処理することです。 –

+0

私のOSは、毎日何十億ものユーザーによってソークテストされています。私は本当に良いコードを書いていると思っていますが、同じ量のテストはできませんので、可能な限りOSを活用しようとしています。 –

0

実行されていないデストラクタ(sharptooth pointer out)に加えて、グローバルオブジェクトを削除してメモリチェッカを幸せにする価値があります。特にあなたのコードが共有ライブラリにある場合、適切に削除しなかっただけで、メモリーチェッカー(例:Valgrind)の出力が乱雑にならないようにする必要があります。

+0

No.アップサイド - valgrindに偽のリークログはありません。ダウンサイド - シャットダウンメカニズムのコーディング、テスト、およびメンテナンス。 –

+0

@MartinJames:コーディング、テスト、およびメンテナンスは欠点ではありませんが、単純に必要です。グローバルに新しいものが削除されない共有ライブラリを想像してみてください。このライブラリが( 'dlopen' /' LoadLibrary'などを使用して)繰り返しロード/アンロードされると、実際にはより多くのリソースが漏れ続けます。コード、テスト、メンテナンスでこれを処理する必要があります。 –

+0

私は '偽の漏れはありません'と投稿しました。あなたが説明しているようにライブラリが漏れた場合は、確かに、問題を解決してください!私が持っている唯一の問題は、存在しない問題を修正することです。 –

1

正解はありません。ほとんどの場合、おそらく の問題はありませんが、 を超えて重要なことをするデストラクタがあります(テンポラリファイルを削除するものがあります)。 はクリーンアップを主張しています。オブジェクトが他のオブジェクトのデストラクタによって使用されている場合、そのようなオブジェクトを破壊すると、破壊の問題が発生する可能性があります。 デストラクタが単に空きメモリ以外の何かをしない限り、私の一般的なルールは、 を破壊しないことですが、 他の人はデフォルトの異なるセットを好むかもしれません。

2

メモリを再利用しても、すべてをクリーンアップすることをお勧めします。これらのオブジェクトには、おそらくオブジェクトデストラクタによってクリーンアップされるべき他のリソース(共有メモリ、スムーズフォア)が割り当てられる可能性があります。

削除を呼び出さない場合は、これらのリソースを保持する共有ポインタを使用して、アプリケーションが終了したときにそれらが正しくクリーンアップされるようにします。

どのようにアプリケーションをテストしていますか?まともでないテストハーネスの開発を妨げる可能性があります。アプリケーションのテストでは、シャットダウンを再試行して再起動する方法が必要な場合があります。

シンプルなリリースメモリのクリーンアップがさらにあります。

+0

これは確かです。だから、試してテストされた選択肢があれば、自分でやってみることを避けるのが最善です。 –

0

は...その後、あなたは間違いなく例えば、デストラクタのOSは、プロセスを終了する前に、すべてと呼ばれるしたくないような場合がありますスレッドハンドルや他のシグナル(複数の 'join/waitFor'デッドロック)でブロックされ、すべての家計の99%の原因で、私のアプリがきれいに投稿を閉じることはありません。

2)dtorが正しく動作しない場合は、とにかくライブラリに埋め込まれているためです。

3)メモリがプロセススレッドよりも寿命が長い場合は、セグメンテーション/ AVがクローズになります(たとえば、スレッドがクローズ時に書き込み可能なバッファオブジェクトのプールなど)。

4)オブジェクトの破壊がOSに残されなければならないその他の「特殊なケース」。

特別なケースとしてシャットダウンコードを「クリーンアップ」することが非常に多い「特殊ケース」があります。

関連する問題