smart pointers in C++

Smart Pointers

To understand smart pointers we must understand normal pointers. 

By default, objects in C++ are placed on the stack. The stack is sequential, quick-access storage that also doesn’t have a ton of room. It is LIFO, like a pancake stack. The memory management is automatic. 

What do we do when we need more room? We go to the heap. The heap is dynamically allocated memory. That means that we choose when to use it, and when to release it. 

A pointer is how we put things on the heap. It’s an object in the stack that HAS A REFERENCE to a heap location. 

With raw pointers, we create them ourselves, and delete them ourselves. However, there is a risk of leaking memory caused by 

  • Freeing up heap memory that didn’t need to be freed 
  • Forgetting to free up heap memory

Now, we get to smart pointers. These remove us from the responsibility of manually getting rid of memory, but they are still more effective than garbage collection in other languages (which often put everything onto the heap). 

The basic idea is this: What if I told you that a pointer could deallocate itself, instead of you having to manage its memory? That’s what smart pointers do. 

The types of smart pointers are: Unique Pointers, Shared Pointers, and Weak Pointers. 

Unique Pointers are pointers that only exist inside of their scope, like the class they are a member of, or the function they’re declared in. Thus, they are cleaned as soon as they go out of scope, yay! They are called Unique because you cannot copy them (using a copy constructor). You CAN use the move() command, but, this will make the original one unusable. 

But sometimes we actually DO want to share. This is illustrated by the concept of Shared Pointers. These pointers are used for things like textures in games, where more than one object may want to use the same resource. So there are two different pointers, which point to the same location on the heap. C++ is smart enough to manage these for us. It knows how many instances we have of that shared pointer, and it deallocates the memory once they are all gone. 

Then, finally, we have Weak Pointers. These are used for parent-child relationships. Imagine that you have a Parent class that has a pointer to its Child, and the Child also has a pointer to its Parent. The problem is, in order to get rid of a Shared Pointer, you have to call reset() on it – and all that does is get rid of the VARIABLE and decrement the REFERENCE COUNT. It does not actually free the memory. The memory is freed when the REFERENCE COUNT is zero only

If you were to call reset on both the Parent and the Child, their reference counts would remain 1, so the memory would just sit there allocated AND you would have no access to it. 

So we can use a Weak Pointer in the Child, so it can connect with the Parent. But, the Parent now does NOT have the extra +1 to its REFERENCE COUNT, because the Child is just using a weak pointer which does NOT add to that. So when the Parent goes out of scope, the Parent pointer in the Child becomes invalid too (and we determine validity with the lock() function). 


Comments

Popular posts from this blog

6 hours and only 6 Lagoon rides?

Reflecting on major life goals yet again

Hobble Creek Half: The slow passage of time marches us towards our inevitable death