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

发布于 2024-08-30 18:16:50 字数 138 浏览 6 评论 0原文

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

    delete e;
    delete e;
    ...
    delete e;
    return 0;
}
int main() {
    Employee *e = new Employee();

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

披肩女神 2024-09-06 18:16:50

如果您多次尝试通过指针删除对象,则会出现未定义的行为

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

You get undefined behaviour if you try to delete an object through a pointer more than once.

This means that pretty much anything can happen from 'appearing to work' to 'crashing' or something completely random.

高跟鞋的旋律 2024-09-06 18:16:50

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

可能发生的事情很糟糕。通常,空闲存储是一个精心管理的空闲和分配块系统,并且newdelete进行簿记以保持所有内容处于一致状态。如果您再次删除,系统很可能会对无效数据进行相同的簿记,并且突然免费存储处于不一致状态。这称为“堆损坏”。

一旦发生这种情况,您使用 newdelete 执行的任何操作都可能会产生不可预测的结果,其中可能包括尝试在应用程序的内存区域之外写入、默默地损坏数据、错误地认为没有更多内存,或者双重或重叠分配。如果幸运的话,程序很快就会崩溃,尽管您仍然无法找出原因。如果你运气不好,它会继续运行并带来不好的结果。

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. 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. 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. 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.

独享拥抱 2024-09-06 18:16:50

除了关于“未定义行为”的老说法,即任何事情都可能发生,从无到有,直到进入主内存中打开的地狱第七圈,实际上在大多数实现中通常会发生的是该程序将继续运行过去的删除,然后在某些不相关的内存分配中神秘地崩溃。

Aside from the old saw about "undefined behavior" meaning anything could happen from nothing to a gateway to the seventh circle of the inferno opening up in main memory, in practice what will usually happen in most implementations is that the program will continue to run past the deletes, and then mysteriously crash sometime later in some unrelated memory allocation.

一刻暧昧 2024-09-06 18:16:50

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

在许多系统上这会导致崩溃;例如,在我的 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]

You are likely venturing into 'undefined behavior' territory.

On many systems this will cause a crash; for example, on my Linux machine:

*** 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]
吐个泡泡 2024-09-06 18:16:50

如果你真的很幸运,它会崩溃。通常发生的情况是,它会积累业力,直到您的首席执行官向您最重要的新客户演示代码,此时它将损坏/破坏他们的所有数据。

在检查或调试版本中,通常会捕获这种情况,但它可能完全未被检测到并在以后造成严重破坏。当涉及多个线程时,这一点尤其重要。

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.

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.

坦然微笑 2024-09-06 18:16:50

如果您担心这种情况可能会在您的应用中发生,请完全停止使用原始指针,这样您就不需要删除(例如切换到 shared_ptr),或者始终将指针设置为 NULL< /code> (或 0,或者更好的是 nullptr),删除它们后。对空指针调用delete 保证不会执行任何操作。

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. Calling delete on a null pointer is guaranteed to do nothing.

浅黛梨妆こ 2024-09-06 18:16:50

它不安全,并且未定义实际可能发生的情况:

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

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

苍风燃霜 2024-09-06 18:16:50

即使有时我们可以在删除 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

Even though sometimes we can access the memory location after deleting ptr.
we shouldn't delete same pointer again or assign value to that pointer( leads to inconsistent behavior).

But we can use same pointer variable to point different memory address ( valid memory)

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;

leads to output

in main
10
0x558b597a8eb0
0x7fff8f7a5ba0
in main2 after delete
0
0x558b597a8eb0
0x7fff8f7a5ba0
in main3
100
0x558b597a8eb0
0x7fff8f7a5ba0
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文