steffen
steffen

Reputation: 8968

Strange segfault with unique_ptr and shared_ptr

I came accross a strange segfault. The cause actually led me to a bug, but I still don't understand why a segmentation fault is caused here... The code is:

#include <memory>
int main(int argc, char **arv)
{
    int *i = new int;
    std::unique_ptr<int> u1(i);
    std::unique_ptr<int> u2;
    u1 = std::move(u2); // line 7
    std::shared_ptr<int> s1(i); // line 8
    std::shared_ptr<int> s2;
    s2 = s1;
}

I compile with g++ 4.6 and -std=c++0x and get a segfault.

If I change line 7 to u2 = std::move(u1); (that was the bug) it disappears. If I change line 8 to std::shared_ptr<int> s1(new int(3)); (which of course I don't want) it also disappears. If I remove from line 8 on also no segfault.

So no harm done, but I don't understand why there should be a segfault. As far as I understand,
in line 7 an empty pointer is assigned to u1. No reset(), no end of scope. Nevertheless i seems to be invalid from there on. Is that intented? That means one has to be very very careful when moving a pointer because another object could be destroyed!

What do you think? How do I protect myself from this?

Thanks, Steffen

Upvotes: 3

Views: 5850

Answers (2)

Kerrek SB
Kerrek SB

Reputation: 477434

Your line 8 is wrong: Once you capture i in the unique_ptr, you must not again give it to some other ownership-taking object! Every owner will attempt to delete *i, which is wrong.

Instead, you should create the shared pointer from the unique pointer:

std::shared_ptr<int> s1(std::move(u2));

(Also, you have u1 and u2 the wrong way round.)

Upvotes: 11

mfontanini
mfontanini

Reputation: 21910

This line:

u1 = std::move(u2);

Makes the previous pointer stored by u1 to be deleted. Therefore, your i pointer gets freed. Creating a shared_ptr holding the free'd pointer is undefined behaviour.

Upvotes: 4

Related Questions