Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shared pointer double deleting

Tags:

c++

shared-ptr

I have an object that is apparently double deleted despite being kept track of by smart pointers. I am new to using smart pointers so I made a simple function to test whether I am using the object correctly.

int *a = new int(2);

std::shared_ptr<int> b(a);
std::shared_ptr<int> c(a);

This set of lines in the main function causes a runtime error as the pointers go out of scope, why? Aren't smart pointers supposed to be able to handle the deletion of a by themselves?

like image 851
user3639950 Avatar asked Dec 14 '22 22:12

user3639950


2 Answers

A shared_ptr expects to own the pointed-at object.

What you've done is to create two separate smart pointers, each of which thinks it has exclusive ownership of the underlying int. They don't know about each other's existence, they don't talk to each other. Therefore, when they go out of scope, both pointers delete the underlying resource, with the obvious result.

When you create a shared_ptr, it creates a sort of "management object" which is responsible for the resource's lifetime. When you copy a shared_ptr, both copies reference the same management object. The management object keeps track of how many shared_ptr instances are pointing at this resource. An int* by itself has no such "management object", so copying it does not keep track of references.

Here's a minimal rewrite of your code:

// incidentally, "make_shared" is the best way to do this, but I'll leave your
// original code intact for now.
int *a = new int(2);

std::shared_ptr<int> b(a);
std::shared_ptr<int> c = b;

Now, they both reference the same underlying management object. As each shared_ptr is destroyed, the number of references on the int* is reduced and when the last reference goes ther object is deleted.

like image 147
Rook Avatar answered Dec 17 '22 11:12

Rook


You are only allowd to make a smartpointer once from a raw pointer. All other shared pointers have to be copies of the first one in order for them to work correctly. Even better: use make shared:

 std::shared_ptr<int> sp1 = std::make_shared<int>(2);
 std::shared_ptr<int> sp2 = sp1;

EDIT: forgot to add the second pointer

like image 43
MikeMB Avatar answered Dec 17 '22 13:12

MikeMB