0

次のコードは、デストラクタが 2 回呼び出されるようにします。

#include <iostream>
#include <memory>
#include <exception>
#include <cstdlib> 

void myterminate()
{
    std::cout << "terminate\n";
    abort();
}

class data 
{
    int a;
public:
    data(int a) : a(a) { std::cout << "ctor " << a << "\n"; }
    ~data() { std::cout << "dtor " << a << "\n"; }
    static data failure(int a) { return data(a); }
};

void main()
{
    std::set_terminate(myterminate); //terminate is not called
    try
    {
        std::unique_ptr<data> u;
        u.reset(&data::failure(1));
        std::cout << "no worries\n"; //this prints 
        //destructor called at try-block end and attempt to destruct an invalid memory block.
    }
    catch (...)
    {
        std::cout << "caught\n"; //this can not catch the error
    }
    std::cout << "end\n"; //program crash, will not be called
}

本番環境でこのようなエラーをキャッチするにはどうすればよいですか?

リリース ビルドでは、プログラムがクラッシュします。デバッグビルドでは、私のシステムでは次のようになります。 ここに画像の説明を入力

4

3 に答える 3

1

「try/catch」のようなミスはキャッチされません。この場合、クラッシュの可能性が高いからです。しかし、信号を使用してキャッチしようとすることができる破壊の瞬間と、より威厳のあるプログラムを終了します。目をそらす: #include 、 signal()、 sig_atomic_t ...

于 2016-01-26T11:05:08.020 に答える
0

最初に、標準が§ 3.6.1で2つのフォームのみを許可する場所mainとして宣言するコメントに記載されているようにvoid main

  1. 実装は、メイン関数を事前定義してはなりません。この関数はオーバーロードされません。int 型の戻り値の型が宣言されている必要がありますが、それ以外の場合、その型は実装定義です。実装では、両方を許可する必要があります

    (2.1) — int を返す () の関数と

    (2.2) — int を返す (int、char へのポインターへのポインター) の関数

次に、スコープの最後で破棄されるとd になり、未定義の動作がunique_ptr発生する一時を管理するようにリセットしています。未定義の動作に起因するエラーを予測/キャッチすることはできません。unique_ptrdelete

何をすべきか(動的に割り当てられたメモリを本当に使用したい場合)、ヒープ上のオブジェクトへのポインタを返すことができます:

#include <iostream>
#include <memory>
#include <exception>
#include <cstdlib> 

void myterminate()
{
    std::cout << "terminate\n";
    abort();
}

class data 
{
    int a;
public:
    data(int a) : a(a) { std::cout << "ctor " << a << "\n"; }
    ~data() { std::cout << "dtor " << a << "\n"; }
    static data* failure(int a) { return new data(a); }
};

int main()
{
    std::set_terminate(myterminate); //terminate is not called
    try
    {
        std::unique_ptr<data> u;
        u.reset(data::failure(1));
        std::cout << "no worries\n"; //this prints 
        //destructor called at try-block end and attempt to destruct an invalid memory block.
    }
    catch (...)
    {
        std::cout << "caught\n"; //this can not catch the error
    }
    std::cout << "end\n"; //program crash, will not be called
}

オンライン コード: http://melpon.org/wandbox/permlink/pdiijgDxBshVOYRu

于 2016-01-26T10:07:48.063 に答える