26
int main() {
    Employee *e = new Employee();

    delete e;
    delete e;
    ...
    delete e;
    return 0;
}
4

8 回答 8

43

如果您多次尝试通过指针访问对象,则会得到未定义的行为。delete

这意味着几乎任何事情都可能发生,从“看起来工作”到“崩溃”或完全随机的事情。

于 2010-04-30T18:13:41.300 回答
19

这是未定义的行为,所以任何事情都可能发生。

可能发生的事情很糟糕。通常,免费存储是一个精心管理的免费和已分配块系统,newdelete进行簿记以使所有内容保持一致状态。如果你delete再看一遍,系统很可能对无效数据做同样的记账,突然空闲存储处于不一致的状态。这被称为“堆损坏”。

一旦发生这种情况,您所做的任何事情newdelete可能会产生不可预知的结果,其中可能包括尝试在应用程序的内存区域之外写入、默默地破坏数据、错误地认为没有更多的内存,或者双重或重叠分配。如果幸运的话,程序很快就会崩溃,尽管你仍然无法弄清楚原因。如果你不走运,它会继续运行,结果很糟糕。

于 2010-04-30T18:19:19.640 回答
13

除了关于“未定义行为”的旧观点,这意味着任何事情都可能发生,从无到有通往主内存中打开的地狱第七圈的网关,实际上,在大多数实现中通常会发生的是程序将继续运行过去删除,然后在稍后的某个不相关的内存分配中神秘地崩溃。

于 2010-04-30T18:17:08.347 回答
4

您可能正在冒险进入“未定义行为”领域。

在许多系统上,这会导致崩溃;例如,在我的 Linux 机器上:

*** glibc detected *** ./cctest: double free or corruption (fasttop): 0x0000000000d59900 ***
======= Backtrace: =========
/lib/libc.so.6[0x7f399f4cbdd6]
/lib/libc.so.6(cfree+0x6c)[0x7f399f4d074c]
./cctest[0x400a7a]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f399f474abd]
./cctest[0x400959]
于 2010-04-30T18:15:31.467 回答
3

如果你真的很幸运,它会崩溃。通常情况下,它会存储业力,直到您的 CEO 向您最重要的新客户展示代码,此时它将破坏/破坏他们的所有数据。

在检查或调试版本中,这种事情经常被捕获,但它可能完全未被发现并在以后造成严重破坏。当涉及多个线程时,这一点尤其深刻。

于 2010-04-30T18:48:28.427 回答
3

如果您担心这可能会在您的应用程序中发生,请完全停止使用原始指针,这样您就不需要删除(例如切换到),或者在删除它们后shared_ptr始终将指针设置为NULL(或 0,或者更好)。nullptr对空指针调用 delete 保证什么都不做。

于 2010-04-30T20:38:00.373 回答
2

这不安全,并且不确定实际发生的情况:

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.2

于 2010-04-30T18:13:48.737 回答
0

即使有时我们可以在删除 ptr 后访问内存位置。我们不应该再次删除相同的指针或为该指针赋值(导致不一致的行为)。

但是我们可以使用相同的指针变量来指向不同的内存地址(有效内存)

int *p = new int(10);
std::cout << "in main" << std::endl;
std::cout <<*p << std::endl;
std::cout << p << std::endl;
std::cout << &p<< std::endl;
delete p;
std::cout << "in main2 after delete" << std::endl;
std::cout <<*p << std::endl;
std::cout << p << std::endl;
std::cout << &p<< std::endl;

p = new int(100);
std::cout << "in main3" << std::endl;
std::cout <<*p << std::endl;
std::cout << p << std::endl;
std::cout << &p<< std::endl;

导致输出

in main
10
0x558b597a8eb0
0x7fff8f7a5ba0
in main2 after delete
0
0x558b597a8eb0
0x7fff8f7a5ba0
in main3
100
0x558b597a8eb0
0x7fff8f7a5ba0
于 2021-09-30T09:09:00.780 回答