其他分享
首页 > 其他分享> > c – 为什么我必须在“原始”指针上调用delete?

c – 为什么我必须在“原始”指针上调用delete?

作者:互联网

我想知道为什么在下面的代码中第一次删除不会释放内存:

#include <list>
#include <stdio.h>

struct abc {
    long a;

    abc() {
        puts("const");
    }
    ~abc() {
        puts("desc");
    }
};

int main() {

    std::list<abc*> test;

    abc* pA = new abc;
    printf("pA: 0x%lX\n", (unsigned long int)pA);
    test.push_back(pA);

    abc* pB = test.back();

    printf("pB: 0x%lX\n", (unsigned long int)pB);
    delete pB; // just ~abc()

    test.pop_back();

    delete pA; // ~abc() and free (works)

    puts("before double-free");

    delete pA; // ~abc() and second free (crash)

    return 0;
}

输出是:

const
pA: 0x93D8008
pB: 0x93D8008
desc
desc
before double-free
desc
*** glibc detected *** ./test: double free or corruption (fasttop): 0x093d8008 ***
...

我尝试了free()也行为相同.

解决方法:

delete pA; // ~abc() and free (works)

puts("before double-free");

delete pA; // ~abc() and second free (crash)

一旦编写delete pB,就不需要这些delete语句.你错误地认为delete pB只调用析构函数.不,它调用析构函数并释放内存.

此外,由于您已经编写了删除pB,接下来的两个删除表达式会调用undefined behavior,这意味着任何事情都可能发生:程序可能会也可能不会崩溃!

看看这些主题:

> Undefined, unspecified and implementation-defined behavior
> Is there any way to predict the undefined behaviour or implementation defined behaviour?
> What are all the common undefined behaviours that a C++ programmer should know about?

标签:c,pointers,memory,delete-operator
来源: https://codeday.me/bug/20190726/1540427.html