简体   繁体   中英

Is this a double free in C++

I thought the following code snippets would cause double free, and the program would core dump. But the truth is that there is no error when I run the code?

Similar problem shows that it caused double free!

My Question is why does there have no error show that there is a double free? And why does there have no core dump?

#include <iostream>
using namespace std;

int main()
{
    int *p = new int(5);
    cout << "The value that p points to: " << (*p) << endl;
    cout << "The address that p points to: " << &(*p) << endl;
    delete p;
    cout << "The value that p points to: " << (*p) << endl;
    cout << "The address that p points to: " << &(*p) << endl;
    delete p;
    cout << "The value that p points to: " << (*p) << endl;
    cout << "The address that p points to: " << &(*p) << endl;
    delete p;
}

The program's output when I ran this program is shown as followed: 程序输出

After modifying the code snippet like the following, the core dump occured:

#include <iostream>
using namespace std;

int main()
{
    int *p = new int(5);
    for (;;)
    {
        cout << "The value that p points to: " << (*p) << endl;
        cout << "The address that p points to: " << &(*p) << endl;
        delete p;
    }
    return 0;
}

And the program output is : 修改后的程序输出

So there is another question that why this program will core dump every time?

Yes, it is a double free (well, triple, really) which puts it into undefined behaviour territory.

But that's the insidious thing about undefined behaviour, it's not required to crash or complain, it's not required to do anything at all (a) . It may even work.

I can envisage an implementation that stores the free state of a block in the control information for it so that freeing it twice would have no effect. However, that would be inefficient, and also wouldn't cover the case where it had been reallocated for another purpose (it would prevent double frees, but not a piece of code freeing the block when some other piece still thinks it still has it).

So, given it's not required to work, you would be well advised to steer clear of it since it may also download maniacal_laughter.ogg and play it while erasing your primary drive.

As an aside, modern C++ has smart pointers that are able to manage their own lifetime, and you would be doing yourself a big favour if you started using those instead of raw pointers.
And, although the removal of raw pointer from C++ was a joke, there are some that think it's not such a bad idea :-)


(a) The C++20 standard has this to say when describing undefined behaviour in [defns.undefined] (my emphasis):

Behavior for which this document imposes **NO** requirements.

why does there have no error show that there is a double free? And why does there have no core dump?

delete p;
cout << "The value that p points to: " << (*p) << endl;

The moment you referenced to a deleted pointer is when the program entered an undefined behaviour, and then there is no guarantee that there would be an error or a crash.

It's not entirely the same, but the analogy between memory and a hotel room is applicable, which explains well what an undefined behaviour means. Highly recommended reading:

Can a local variable's memory be accessed outside its scope?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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