there are multiple missunderstandings, but i will try to explain:
in c++ objects are either stored on the stack or the heap. objects created on the stack will get destroyed and their memory gets released as soon as you leave the scope in which they are declared. this happens full automatically for you. for example:
int bla()
{
int a = 1;
int b = 2;
int result = a+b;
return result;
}
in this example the 3 int
objects will get created when the programm enter the function bla
and will get destroyed when the function returns accordingly.
then you have the heap. you can create objects on the heap via new
. this objects outlive the scope in which they got created, but you have to remember to destroy the objects via delete
. because this is a common pitfall and source for memoryleaks the standard library provides helper classes (for example the shared_ptr
which you already found) to overcome this issue. the idea is, that the shared_ptr
object will take the responsibility to delete the given object (which has to be on the heap(!) (yeah you can bypass this by a custom deleter, but thats a little bit more advanced than this explanation)) as soon as the shared_ptr itself gets destroyed. like the name suggests, the shared_ptr
's intend is to be shared. to be shared you just copy the shared_ptr.
the shared_ptr
implementation has a custom copy constructor and copy assignment operator which will handle this by incrementing the use count and copying the address of the object that is currently handled. and this is the only way how a shared_ptr object will get to know wether there are other instances managing the same object or not. so to increase the use count you have to make a copy of the shared_ptr
.
now let me explain what went wrong:
your initial Node node = Node(10);
is created on the stack (like the ints above). so there is no need to manage the lifetime manually. you created a shared_ptr
, managing the address of this node. that is a misstake. as soon as you leave the scope the shared_ptr
AND the node object itself(through the automatism on the stack) are going to delete the node object. and thats bad.
lets imagine error 1 did not exists. so we have a second misstake:
you are creating a second, seperate shared_ptr
instead of copying from the first one. now both existing shared_ptr
dont know about each other and each of them will try to delete the node object. so we have again a double delete.
lets pretend you want your Node object really be managed by a shared_ptr
, you have to start with one shared_ptr and later copy from it as much as you want to share it. to create the first one you have 2 possiblilties:
std::shared_ptr<int> mysharedpointer (new int(ANYNUMBER));
auto mysharedpointer = std::make_shared<int>(ANYNUMBER);
usually you would prefer the second one, since it comes with a slight perfomance advantage and more safety when used in a function call context.
if you now want a second shared_ptr
, sharing ownership with the first, you can do this by copying the first pointer:
auto mysecondsharedpointer = mysharedpointer;
and voila you have a copy associated with the shared ownership.
(this is all a bit simplified and i am sure i missed something. feel free to complete the answer)