2

Why does this code NOT generate a double free when the shared pointers go out of scope?

int main()
{
    {
        auto * ptr = new int(1);
        shared_ptr<int> a( ptr );
        shared_ptr<int> b( ptr );
        cout << "ok: " << *a << *b << endl;
    }
    cout << "still ok" << endl;
    return 0;
}
nyarlathotep108
  • 5,275
  • 2
  • 26
  • 64
  • 1
    Ahhhhhh! I know fear! – user4581301 Jan 27 '18 at 18:26
  • 1
    As other are pointing out, you are actually double deleting a pointer, so you are in the realm of UB. using a class instead of an int can help you to see the proble: see [this](https://ideone.com/I2gnHj) as example – Gian Paolo Jan 27 '18 at 18:32

3 Answers3

6

This code is UB, so anything might happen.

For a delete is called on the already deleted pointer.

Edgar Rokjān
  • 17,245
  • 4
  • 40
  • 67
6

Why does this code NOT generate a double free when the shared pointers go out of scope?

Why do you think it doesn't?

It's undefined behavior, anything can happen. That includes your program printing out still ok.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • Truth is: I was erroneously thinking that it wasn't crashing only because on my machine it was not crashing. I forgot that undefined behavior is a thing. – nyarlathotep108 Jan 27 '18 at 18:29
4

Constructing more than one shared pointer from a raw pointer results in undefined behavior because:

the pointed-to object will have multiple control blocks.

Excerpt from the "Effective Modern C++", page 129, item 19

Avoid passing raw pointers to a std::shared_ptr constructor. If you really must use raw pointers then use the result of a operator new instead of a pointer:

std::shared_ptr<int> a(new int(1));

or use the std::make_shared macro:

std::shared_ptr<int> a = std::make_shared<int>(1);

and create a second shared pointer by passing a as an argument to the constructor:

std::shared_ptr<int> b(a);
Ron
  • 14,674
  • 4
  • 34
  • 47