2017-05-17 14 views
1

delete()でクラッシュしました。私はtry-catchでdelete()を折り返して正しく処理しようとしますが、catchセクションに落ちる代わりにクラッシュしました。ダブルフリーでキャッチしてください。

私がしようとしているものの例です。

int *i = new int(); 
delete (i); 
try { 
    delete (i); 
}catch (...) { 
    std::cout << "Oops"; 
} 

質問は「なぜ私はこのように捕まえられないのですか? 「このような状況をどうやって適切に捕まえることができるのか?」

+0

どのコンパイラ/ OSを使用しますか? – Ari0nhh

+0

http://stackoverflow.com/questions/43074727/a-pointer-that-c​​an-point-to-anywhere-how-to-determine-if-delete-can-be-safely/43077127# 43077127ここに。質問はあなたのものに似ています。 – Sniper

+0

std :: unique_ptr!を使用してください。 –

答えて

5

delete演算子は例外をスローしません:noexcept

(C++ 11以降):

noexcept仕様(C++ 11時まで)

例外(なし) cf cppreference

二重削除はプログラミングエラーです。あなたはそれを処理しようとすべきではありません:それらを取り除くためにデバッグツールを使用してください(そして、RAIIとRAIIを使用する標準クラスでより良いメモリ管理)

+0

ダブル削除は未定義の動作であることに注意してください。言い換えれば、何かが起こる可能性があり、「何か」に例外を投げる 'noexcept'関数が含まれています!それでも、結論は正しいです:それを処理しないでください、それを防ぐ。 (+1) – MSalters

+1

例外をスローするnoexcept関数はstd :: terminate()を呼び出します(デフォルトではstd :: abortを呼び出します) – nefas

+0

これは具体的なルールですが、未定義ビヘイビアルールは他のすべてのルールよりも優先されます。 – MSalters

1

削除は例外的な操作ではないので、それをキャッチすることはできません。

-2

変数が削除されたかどうか。それができない場合は、削除の代わりにreallocを使用してみてください。

+0

どのように_that_変数を取り除く予定ですか? 2番目の変数が削除されるかどうかを追跡するために3番目の変数が必要です。そして、4番目に... – MSalters

+0

@MSaltersスタック変数を使用する予定です。スタック変数は、プログラムが終了すると自動的に削除されます。 – AppWriter

+0

はグローバル変数です。そして問題はグローバル変数を使用することですか?アイテムのリンクされたリストには、何千ものノードがあり、全て 'new'で割り当てられています。それに、あなたがしたのなら、どうしてあなたはそのリストをグローバルにしませんでしたか? – MSalters

-1

ポインタを削除すると、nullptrNULL)に設定されます。 delete nullptrは有効な操作です。

は、それがスコープの外に出るときには、ポインタを削除します(あなたが早期に帰国し、適切なものを削除しませ心配している場合、あなたはスコープの自動削除書くことができます。..のような

#ifndef SAFE_DELETE 
#define SAFE_DELETE(pPtr) { delete pPtr; pPtr = 0; } 
#endif 

をマクロを使用します関数やブロックからの復帰など)。

#ifndef SCOPED_AUTO_SAFE_DELETE 
template <typename T> 
class ScopedAutoDeletePointerHelper 
{ 
public: 
    ScopedAutoDeletePointerHelper(T pPtr) : _pPtr(pPtr) {} 
    ~ScopedAutoDeletePointerHelper() { delete (_pPtr); } 

    T _pPtr; 
}; 
#define SCOPED_AUTO_SAFE_DELETE(p) ScopedAutoDeletePointerHelper<decltype(p)> anAutoDelete##p(p); 
#endif 
+1

この答えは正しく始まりました。そして、 'if(pPtr)delete pPtr;'と言って矛盾します。 'delete'自体が同じチェックをしているので、それは無意味です。次に、マクロ(関数も同様に機能し、より安全です)と、ちょっと変わったクラスの提案があります。デストラクタでメンバを 'nullptr'に設定する必要はありません。メンバーは、dtorが返った後でさえも_exist_しません。 – MSalters

+0

一般的に、削除後にメンバーをnullptrに設定するのは、冗長であっても(特にそうではありませんが)良いプラクティスです。 –

+0

これはC++では必要ありません。私たちはすでに 'std :: unique_ptr'を持っています。これは、あなたがそれらのゴドガルなマクロを扱うことを意図した質問に対するきれいな答えです。申し訳ありませんが、質問された質問に対処できず、役に立たない解決策を提供していないため-1です。 – IInspectable

関連する問題