简体   繁体   English

当你在 C++ 中释放一个指针两次或更多次时会发生什么?

[英]What happens when you deallocate a pointer twice or more in C++?

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

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

You get undefined behaviour if you try to delete an object through a pointer more than once.如果您尝试多次通过指针delete对象,则会出现未定义的行为

This means that pretty much anything can happen from 'appearing to work' to 'crashing' or something completely random.这意味着几乎任何事情都可能发生,从“似乎可以工作”到“崩溃”或完全随机的事情。

It's undefined behavior, so anything can happen.这是未定义的行为,所以任何事情都可能发生。

What's likely to happen is bad.可能发生的事情很糟糕。 Typically, the free store is a carefully managed system of free and allocated blocks, and new and delete do bookkeeping to keep everything in a consistent state.通常,空闲存储是一个精心管理的空闲块和已分配块系统, newdelete簿记以保持所有内容处于一致状态。 If you delete again, the system is likely to do the same bookkeeping on invalid data, and suddenly the free store is in an inconsistent state.如果再次delete ,系统很可能对无效数据做同样的记账,突然空闲存储处于不一致状态。 This is known as "heap corruption".这被称为“堆损坏”。

Once that happens, anything you do with new or delete may have unpredictable results, which can include attempting to write outside the application's memory area, silently corrupting data, erroneously thinking there's no more memory, or double or overlapping allocation.一旦发生这种情况,您对newdelete执行的任何操作都可能会产生不可预测的结果,其中可能包括尝试在应用程序的内存区域之外写入、默默地破坏数据、错误地认为没有更多内存,或者重复分配或重叠分配。 If you're lucky, the program will crash soon, although you'll still have problems figuring out why.如果幸运的话,该程序很快就会崩溃,尽管您仍然无法找出原因。 If you're unlucky, it will continue to run with bad results.如果你不走运,它会继续运行,结果很糟糕。

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

You are likely venturing into 'undefined behavior' territory.您可能正在冒险进入“未定义行为”领域。

On many systems this will cause a crash;在许多系统上,这会导致崩溃; for example, on my Linux machine:例如,在我的 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]

If you're really lucky it will crash.如果你真的很幸运,它会崩溃。 What normally happens is it stores up karma until your CEO is demonstrating the code to your most important new customer when it will corrupt/destroy all of their data.通常情况下,它会存储业力,直到您的 CEO 向您最重要的新客户演示代码时,它会损坏/破坏他们的所有数据。

In checked or debug builds often this kind of thing is caught, but it can go completely undetected and cause havoc later.在检查或调试版本中,这种事情通常会被捕获,但它可能完全未被发现并在以后造成严重破坏。 This is especially profound when multiple threads get involved.当涉及多个线程时,这一点尤其重要。

If you are worried this might happen in your apps, either stop using raw pointers completely, so that you don't need delete (eg switch over to shared_ptr ) or always set pointers to NULL (or 0, or better still nullptr ) after you delete them.如果您担心这可能会发生在您的应用程序中,要么完全停止使用原始指针,这样您就不需要删除(例如切换到shared_ptr ),或者在您之后始终将指针设置为NULL (或 0,或者最好还是nullptr )删除它们。 Calling delete on a null pointer is guaranteed to do nothing.对空指针调用 delete 保证什么都不做。

It's not safe, and it's undefined what might actually happen:这不安全,并且不确定实际可能发生的情况:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM