-2

以下のコードは正常にコンパイルされますが、実行されません

#include <iostream>
using namespace std;

int main()
{
    int *a;
    int b = 5;
    a = &b;
    cout << *a << endl;
    delete a;
    return 0;
}

編集:

int main()
{
    int *a = 0;
    delete a;
    return 0;
}

これはうまくいきます。どうしてこんなことに?

4

7 に答える 7

7

編集後、未定義の動作のケースが 1 つだけあり deleteますnew

deleteNULL ポインターでの使用は、害を及ぼさないことが保証されています。しかしdelete、以前に割り当てたり削除したりしなかったメモリは未定義です。私が知っている実装は、ある種のアクセス違反でプログラムを終了します。

于 2013-10-24T11:26:06.840 に答える
1

「未定義の動作」とは、実行したことに対して事後条件が保証されていないことを意味します。

「コンパイラ」が何が起こるかを選択すると、人々はよく言います。実際には、コンパイラーがそれをコンパイルし、ヒープ・マネージャーが実行時に無効な削除呼び出しを呼び出す状況をどのように処理するかを決定します。

ここでのケースは、コンパイラー・レベルでキャッチするのは簡単に見えますが、コンパイラーの範囲を超えているだけの場合が多くあります。

于 2013-10-24T11:36:38.127 に答える
0

スタック メモリを削除しようとしています。スタック内のメモリを削除しようとすると伝染し、未定義の動作が発生します。

ヒープメモリの割り当ては伝染しません。

于 2014-07-23T08:41:15.987 に答える
0

割り当てられていないメモリ位置に書き込もうとしています。

*a = 5;

そして、あなたが割り当てていないメモリを削除しようとしています

を削除します。

未定義の動作があります。

于 2013-10-24T11:21:57.887 に答える
0

newまたはnull ポインターで割り当てられていないポインターでdeleteを呼び出すことは、未定義の動作であり、ドラフト C++ 標準セクションのDelete段落2には次のように記載されています (強調鉱山):5.3.5

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

すべての未定義の動作が可能であるため、プログラムは正常に動作しているように見えることさえありますが、結果は信頼できません。

于 2013-10-24T11:59:01.993 に答える
0

未定義の動作を引き起こします

  1. 未割り当てメモリを使用してデータを保存しています
  2. 割り当てられていないメモリを削除しています

これらの要因はどちらも、「アクセス違反」によるクラッシュを引き起こす可能性が最も高いです。

ただし、動作は定義されていないため、アプリケーションは動作します。

于 2013-10-24T11:18:46.947 に答える