简体   繁体   中英

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

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.)

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.

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