以下代码编译正常但不执行
#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;
}
这很好用。为什么会这样?
答案 0 :(得分:6)
编辑后,您只有一例未定义的行为:
你delete
未获得的new
记忆。
delete
保证不会造成伤害。
但是未定义或未删除之前未分配或删除的内存delete
。我知道的实现会以某种访问冲突退出程序。
答案 1 :(得分:1)
“未定义的行为”意味着您所做的事情没有保证的后置条件。
人们常常会说“编译器”选择会发生什么。实际上,编译器将对其进行编译,并且堆管理器在运行时决定如何处理调用无效删除调用的情况。
虽然这里的情况在编译器级别上看起来微不足道,但在很多情况下,它只是超出了编译器的范围。
答案 2 :(得分:0)
导致未定义的行为
这两个因素都可能导致“访问冲突”崩溃。
但是,由于行为未定义,应用程序可以正常工作。
答案 3 :(得分:0)
您有三种未定义行为:第一种是使用未初始化指针a
取消引用和分配,第二种是打印a
时解除引用,最后一种是删除时a
1}}。
答案 4 :(得分:0)
您正在尝试写入未由您分配的内存位置。
* a = 5;
然后尝试删除未分配的内存
删除a;
它有未定义的行为。
答案 5 :(得分:0)
在尚未使用 new 或空指针分配的指针上调用 delete 是undefined behavior草案C ++标准部分5.3.5
删除段 2 说(强调我的):
[...]在第一个替代(删除对象)中,delete的操作数的值可以是空指针值,指向由前一个new-expression创建的非数组对象的指针,或指针到表示这种对象的基类的子对象(1.8)(第10条)。如果不是,则行为未定义。
与所有未定义的行为一样一切皆有可能,程序甚至可以正常工作但结果不可靠。
答案 6 :(得分:0)
您正在尝试删除堆栈内存。如果你试图删除它,那么堆栈内存会有传染性,会发生未定义的行为。
对于堆内存分配不会传染。