2

可能重复:
C++ 删除 - 它删除了我的对象但我仍然可以访问数据?

考虑以下代码:-

#include <iostream>
class Test
{
public:
    int k=10;
};

int main(int argc, const char * argv[])
{
    Test *t = new Test();
    delete t;
    //t1 = NULL;
    t->k=50;
    printf("\n%d",t->k);
    return 0;
}

它的输出是50虽然t被删除了。为什么不崩溃?我在 Mac OS x 中使用 Xcode。

4

3 回答 3

2

“删除”只会通知(除了调用析构函数之外)堆管理器,之前使用 new 分配的 sizeof(Test) 的内存块将不再使用,并且堆管理器可以自由地对该内存块做任何事情.

让我试着给你一个场景,说明相同的代码何时会导致异常。

假设内存块是由堆管理器在一个新的内存页面上分配的,而堆管理器从虚拟内存管理器获得了新的内存页面,因为它无法在先前分配的页面中的其他任何地方找到空闲空间。现在,当删除完成时,堆管理器会发现在内存页面上分配的唯一块已被释放,因此它可能决定将内存页面释放回虚拟内存管理器。然后,当您的代码访问虚拟内存中甚至不存在页面的内存时,您会收到错误消息。

当然,通过对堆管理实现的深入了解,还可以提出其他方案。

于 2012-11-05T05:42:19.567 回答
1

因为你(不)幸运。您正在调用未定义的行为。一种可能的未定义行为是“按预期工作”。但是,您的期望值得怀疑。在删除和该函数分配内存的使用之间添加一个函数调用等等,您可能会因为判断错误而完全破坏其他一些数据。

未定义的行为不必崩溃……或者不必立即崩溃。但是从长远来看,调用它通常会导致问题,尤其是在更大的程序中。

于 2012-11-05T05:24:09.653 回答
0

这是一个未定义的行为,你不应该期待任何事情。但是,内存可能还没有被写入,它只是被标记为空闲,它最终会被覆盖,这可能就是它工作的原因。将指针设置为 是一个好习惯NULL,为避免此类陷阱,请参阅悬空指针问题。

于 2012-11-05T05:23:29.167 回答