2017-08-10 27 views
2

私はRAIIを使用していて、例えば、メモリがリークしないようにtry/catchを使用しています。 、原因std::unique_ptrでstackunwindingとRAIIを使用してデストラクタが呼び出されないのはなぜですか?

#include <iostream> 
using namespace std; 

void g(){ 
    throw 5; 
} 

class Rand{ 
public: 
    ~Rand(){ 
     cout << "Randomm Destructor called" << endl; 
    } 
    int a = 17; 
}; 

void f(){ 
    auto p = std::make_unique<Rand>(); //Should call dtor 
    Rand* r = new Rand(); //Shouldnt call dtor 
    cout << p->a << endl; //Prints 17 
    g(); 
    cout << "This never executes" << endl; 
} 


int main(){ 
    f(); 
} 

例外がされているため、スタック割り当てられたオブジェクトのデストラクタthrow/tryへの基本的な保証として呼ばれることべきではありません。ここではC++で実装したものです投げられた? throwから

+3

キャッチブロックがないので、巻き戻しが実行されない可能性があります。メインでgの例外をキャッチしてみてください。 –

+0

@NicholasWilson、巻き戻しが起こらない場合はどうなりますか? * – Bana

+1

例外処理のためにアプリケーションが終了した後、OSはメモリを解放しますが、デストラクタは実行されません。それじゃない? – hrust

答えて

5

制御フローは、コールスタックを移動させるよう

を巻き戻しスタックは、デストラクタは、構成された自動記憶域期間を持つすべてのオブジェクトの 呼び出され、なく はまだので、を破壊し対応するtry-blockはに入力され、そのコンストラクタの完了の逆順は です。

コードに対応するtryブロックがないため、デストラクタは呼び出されず、プログラムは終了します。

あなたのようにプログラムを変更する場合:

try 
{ 
    auto p = std::make_unique<Rand>(); //Should call dtor 
    Rand* r = new Rand(); //Shouldnt call dtor 
    cout << p->a << endl; //Prints 17 
    g(); 
    cout << "This never executes" << endl; 
} 
catch (int) {} 

あなたはunique_ptrにラップされたオブジェクトのデストラクタが呼び出されることを、表示されます。

関連する問題