0

これを理解するには、コードから始めるのが最善です

#include "Hello1.h"
#include "Hello2.h"

int main(int argc, char ** argv)
{
    // Hello1 and Hello2 are derevied classes of Hello
    // And there constructor throws an exception
    Hello * h;

    try
    {
        if (argv[1][0]=='1')
            h = new Hello1;
        else
            h = new Hello2;
    }
    catch (std::exception ex) { /*print error*/ }

    delete h;
}

Hello1Hello2例外がスローされた場合、それは segfault . ただし、追加すると

Hello h = NULL;

できます!!!

Hello は、例外をスローするコンストラクタを持つクラスです

私が考えることができるのは、コンストラクターの例外がメモリからオブジェクトを削除することだけです! なぜどこで誰が...説明してください!お願いします。

4

3 に答える 3

6

ただし、追加するHello h = NULL;と機能します!!! なぜどこで誰が...説明してください!お願いします。

これはoperator delete、ポインターが の場合は何もしないためですnull。何もしないことが期待されています。これが標準的な動作です。C++11 標準の 3.7.4.2 項では、次のように指定されています。

[...] 割り当て解除関数に提供される最初の引数の値は、NULL ポインター値である可能性があります。その場合、および割り当て解除関数が標準ライブラリで提供されているものである場合、呼び出しは効果がありません。[...]

null一方、そうでない場合は、operator deleteが指すオブジェクトを削除しようとしhello、ポインターが初期化されていないため (構造がスローされ、割り当てが発生する前に制御が例外ハンドラーに転送されたためhello)、未定義の動作が発生します。

パラグラフ 5.3.5/2 によると:

[...] 最初の選択肢 ( delete object ) では、オペランドの値はdeletenull ポインター値、前の new 式によって作成された非配列オブジェクトへのポインター、またはサブオブジェクトへのポインター ( 1.8) そのようなオブジェクトの基本クラスを表す (第 10 節)。そうでない場合、動作は undefinedです。[...]

于 2013-05-02T09:13:17.853 に答える
1

なぜどこで誰が...説明してください!お願いします。

IfHelloのコンストラクター throwshが初期化されない場合 -deleteその初期化されていない変数と未定義の動作から読み取ろうとします。

スマートポインターの使用をお勧めします。

于 2013-05-02T09:13:29.847 に答える
0

delete削除してはいけないものを削除しようとすると、例外がスローされる可能性があります。他の人が指摘しているように、delete設定されているものを削除しようとするとスローされませんnull

new私の知る限り、メモリが不足していない限り、スローすることはありません。

つまり、 hargv[1]'1'不明な何かを指していてdelete、例外がスローされます。

于 2013-05-02T09:22:59.290 に答える