Reputation: 8968
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
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
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