2

私の質問には2つの部分があります。

  • メモリの割り当て後、解放する前にセグメンテーション違反が発生した場合、これによりメモリがリークする可能性があります(つまり、メモリが解放されることはなく、メモリリークが発生します)。
  • もしそうなら、セグメンテーション違反の場合に割り当てられたメモリがクリーンアップされることを保証する方法はありますか?

C ++でのメモリ管理について読んでいますが、特定の質問について何も見つかりませんでした。

4

5 に答える 5

5

セグメンテーション違反が発生した場合、OSはプログラムが保持するすべてのリソースをクリーンアップする責任があります。

編集:

最新のオペレーティングシステムは、プログラムの終了方法に関係なく、リークされたメモリをクリーンアップします。メモリは、プログラムの存続期間中のみリークされます。ほとんどのOSは、開いているファイルやソケット接続など、他の多くの種類のリソースもクリーンアップします。

于 2012-06-18T16:32:19.280 に答える
4

メモリの割り当て後、解放する前にセグメンテーション違反が発生した場合、これによりメモリがリークする可能性があります(つまり、メモリが解放されないためにメモリリークが発生する可能性があります)。

はい、いいえ:クラッシュするプロセスは、OSによって完全に結び付けられている必要があります。ただし、プロセスによって生成された他のプロセスを考慮してください。それらは完全に終了しない場合があります。ただし、通常、これらはあまり多くのリソースを必要としないはずですが、これはプログラムによって異なる場合があります。http://en.wikipedia.org/wiki/Zombie_processを参照してください

もしそうなら、セグメンテーション違反の場合に割り当てられたメモリがクリーンアップされることを保証する方法はありますか?

プログラムが重要ではない場合(つまり、プログラムがクラッシュしても危険にさらされていない場合)、セグメンテーション違反を修正することをお勧めします。セグメンテーションフォールトを本当に処理できるようにする必要がある場合は、このトピックの回答を参照してください:Linuxでセグメンテーションフォールトをキャッチする方法は?

更新:SIGSEGVシグナルを処理する(そしてプログラムフローを継続する)ことは可能ですが、以下のコメントで指摘されているように、プラットフォームが異なることを意味する未定義の動作であるため、信頼できる安全な方法ではないことに注意してください/ compilers/...は異なる反応をする可能性があります。

したがって、セグメンテーション違反(およびウィンドウでのアクセス違反)を修正する可能性を最優先する必要があります。提案されたソリューションを引き続きこの方法で信号を処理するために使用する場合は、徹底的にテストする必要があります。本番コードに入れる場合は、それを認識し、結果を引き出す必要があります。これは、要件によって異なる可能性があるため、名前を付けません。

于 2012-06-18T16:40:08.093 に答える
2

C ++標準は、それ自体がセグメンテーション違反に関係していません(これはプラットフォーム固有のものです)。

実際には、それは実際にあなたが何をするか、そしてあなたの「メモリリーク」の定義が何であるかに依存します。理論的には、セグメンテーション違反信号のハンドラーを登録できます。このハンドラーで、必要なすべてのクリーンアップを実行できます。ただし、最新のOSは、いずれにせよ、終了プロセスを自動的にクリアします。

于 2012-06-18T16:31:55.680 に答える
0

1つは、システムがクリーンアップを担当するリソースがあります。それらの1つはメモリです。セグメンテーションフォールトでRAMが永続的にリークすることを心配する必要はありません。

2つ目は、システムがクリーンアップの責任を負わないリソースがあります。pidをデータベースに挿入し、閉じるときに削除するプログラムを作成できます。これは、セグメンテーション違反では削除されません。1)ハンドラーを追加して、その種の非システムリソースをクリーンアップするか、2)プログラムのバグを最初に修正することができます。

于 2012-06-18T16:34:27.407 に答える
0

最新のオペレーティングシステムは、アプリケーションのメモリを分離して、アプリケーションの後でクリーンアップできるようにします。セグメンテーション違反の問題は、通常、問題が発生した場合にのみ発生することです。この時点で、デフォルトの動作では、アプリケーションが期待どおりに機能しなくなったため、アプリケーションをシャットダウンします。

同様に、なんらかの奇妙な状況がない限り、アプリケーションがセグメンテーション違反に遭遇した場合に説明できないことを行った可能性があります。したがって、「クリーンアップ」は実際には不可能である可能性があります。許容可能なロールバック状態を保証するために、トランザクションデータベースと同様にメモリを慎重に使用することは可能性の範囲外ではありませんが、そうすること(およびレベルの粒度によっては)は面倒なことではありません。

より実用的なバージョンは、アプリケーションコンポーネント間に独自の種類のサンドボックスを提供し、コンポーネントが停止した場合はコンポーネントを再起動して、以前に保存された許容可能な状態に復元することです。そうすれば、割り当てられたすべてのメモリをフラッシュして、最初から開始することができます。ただし、最後のチェックポイントの時点で保存されていなかったデータはすべて失われます。

于 2012-06-18T16:51:17.923 に答える