-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

编辑后,您只有一种未定义行为的情况: delete您没有获得的记忆new

delete在 NULL 指针上保证不会造成任何伤害。但是delete在你之前没有分配或删除的内存上是未定义的。我知道的实现以某种访问冲突退出您的程序。

于 2013-10-24T11:26:06.840 回答
1

“未定义的行为”意味着您所做的事情没有保证的后置条件。

人们经常会说“编译器”选择了发生的事情。实际上,编译器将编译它,堆管理器在运行时决定它如何处理您调用无效删除调用的情况。

尽管这里的情况在编译器级别上看起来微不足道,但在许多情况下,它只是超出了编译器的范围。

于 2013-10-24T11:36:38.127 回答
0

它会导致未定义的行为

  1. 您正在使用未分配的内存来存储数据
  2. 您正在删除未分配的内存

这两个因素最有可能导致“访问冲突”崩溃。

但是,由于行为未定义,应用程序可以工作。

于 2013-10-24T11:18:46.947 回答
0

您有三种未定义行为的情况:第一种是使用未初始化的指针取消引用和分配a,第二种是打印时取消引用a,最后是删除时a

于 2013-10-24T11:19:47.187 回答
0

对尚未分配new空指针的指针调用delete未定义的行为,草案 C++ 标准部分删除2段说(强调我的):5.3.5

[...]在第一种选择(删除对象)中,delete 的操作数的值可以是空指针值,指向由先前的 new 表达式创建的非数组对象的指针,或指向子对象的指针(1.8) 表示此类对象的基类(第 10 条)。如果不是,则行为未定义。

与所有未定义的行为一样,一切皆有可能,该程序甚至看起来工作正常,但结果不可靠。

于 2013-10-24T11:59:01.993 回答
0

您正在尝试删除堆栈内存。如果您试图删除它,堆栈内存将具有传染性,将发生未定义的行为。

因为堆内存分配不会传染。

于 2014-07-23T08:41:15.987 回答
0

您正在尝试写入不是您分配的内存位置。

*a = 5;

然后尝试删除不是你分配的内存

删除一个;

它具有未定义的行为。

于 2013-10-24T11:21:57.887 回答