C++ 中的悬空指针和删除命令
Danglings Pointers and Delete Command in C++
我注意到我的 C++ 代码中有一些非常奇怪的东西。
class A
{
public:
void doIt(){cout<<"hello"<<endl;}
};
int main() {
A* a=new A();
A* b=a;
delete a;
b->doIt();
return 0;
}
我认为 delete
会从堆中擦除内存,而 b->doIt()
会失败。但是虽然 运行 这段代码有效,甚至可以打印 "hello".
为什么?
这很可能是因为 doIt
方法不使用 A class 的任何内部状态。因此,编译器可能将其优化为静态方法,并在静态 class 上下文中调用调用。指针悬空的事实并不能阻止该方法成为 运行.
但是,这是未定义的行为,更严格的编译器实际上可能会生成确实失败的代码。
I thought that delete will erase the memory from the heap
"erase" 记忆的唯一方法是用锤子。
内存被标记为"unused"并且对象在语义上被销毁。
and b->doIt()
would fail
这是为什么?
没有任何机制可以为您做到这一点,在一般情况下也不会有。
您有责任不对不存在的对象调用函数。
实际上,它不会在这里崩溃,因为 doIt
中没有任何内容实际尝试访问对象的内存。请记住,函数并未存储 "in" 对象 — 它是您程序的一部分,并且您的程序仍然存在。
即使 doIt
访问 and/or 改变了对象的状态,只要该内存仍在活动页面中,您可能 仍然 不会崩溃。这正是 未定义行为 被定义为不可预测的原因。
避免。
- 类似: Can a local variable's memory be accessed outside its scope?
我注意到我的 C++ 代码中有一些非常奇怪的东西。
class A
{
public:
void doIt(){cout<<"hello"<<endl;}
};
int main() {
A* a=new A();
A* b=a;
delete a;
b->doIt();
return 0;
}
我认为 delete
会从堆中擦除内存,而 b->doIt()
会失败。但是虽然 运行 这段代码有效,甚至可以打印 "hello".
为什么?
这很可能是因为 doIt
方法不使用 A class 的任何内部状态。因此,编译器可能将其优化为静态方法,并在静态 class 上下文中调用调用。指针悬空的事实并不能阻止该方法成为 运行.
但是,这是未定义的行为,更严格的编译器实际上可能会生成确实失败的代码。
I thought that delete will erase the memory from the heap
"erase" 记忆的唯一方法是用锤子。
内存被标记为"unused"并且对象在语义上被销毁。
and
b->doIt()
would fail
这是为什么?
没有任何机制可以为您做到这一点,在一般情况下也不会有。
您有责任不对不存在的对象调用函数。
实际上,它不会在这里崩溃,因为 doIt
中没有任何内容实际尝试访问对象的内存。请记住,函数并未存储 "in" 对象 — 它是您程序的一部分,并且您的程序仍然存在。
即使 doIt
访问 and/or 改变了对象的状态,只要该内存仍在活动页面中,您可能 仍然 不会崩溃。这正是 未定义行为 被定义为不可预测的原因。
避免。
- 类似: Can a local variable's memory be accessed outside its scope?