AlgoMaster Logo

unique_ptr

Last Updated: January 3, 2026

6 min read

When we talk about smart pointers, unique_ptr often takes center stage due to its simplicity and efficiency.

Let’s dive into its core features, use cases, and practical applications.

What is unique_ptr?

At its heart, a unique_ptr is a smart pointer that represents sole ownership of an object. When you use unique_ptr, you ensure that there is exactly one pointer managing a resource.

This means that the resource will be automatically freed when the unique_ptr goes out of scope, reducing the chances of memory leaks.

Creating unique_ptr

Creating a unique_ptr is straightforward, and the preferred method is using std::make_unique. This function not only simplifies the syntax but also minimizes the risk of memory leaks that can occur with raw pointers. Here’s how you can create a unique_ptr:

The unique_ptr takes ownership of the resource, and it will automatically clean up when it goes out of scope.

Ownership Transfer

One of the most powerful features of unique_ptr is its ability to transfer ownership. You can’t copy a unique_ptr because ownership should not be duplicated, but you can move it. This is done using std::move, which transfers ownership from one unique_ptr to another.

Here’s an example to illustrate this:

In this case, ptr1 transfers ownership of the Sample object to the process function. After the move, ptr1 becomes null, preventing potential double deletion.

Custom Deleters

Sometimes, you might need more control over how a resource is released. This is where custom deleters come into play. A unique_ptr allows you to specify a custom deleter, which can be especially useful for managing resources that require specific cleanup procedures.

Here’s how you can use a custom deleter:

In this example, CustomDeleter defines how to delete an int. The unique_ptr uses this deleter instead of the default delete, allowing for more flexible resource management.

Common Pitfalls

Despite its benefits, unique_ptr is not without its challenges. Here are some common pitfalls to be aware of:

  1. Moving vs. Copying: Remember that unique_ptr cannot be copied. Attempting to copy will result in a compilation error. Always use std::move when transferring ownership.
  2. Avoiding Dangling Pointers: When you transfer ownership, ensure that the original pointer is no longer used. Accessing it after the move can lead to undefined behavior.
  3. Resource Management: Be mindful of the resources being managed. If you use a unique_ptr with a non-heap allocated resource (like a stack variable), it can lead to problems.
  4. Interoperability: If you're integrating with APIs that expect raw pointers, be cautious when passing unique_ptr. Use get() to retrieve the raw pointer, but remember that this temporarily relinquishes ownership.

Real-World Applications

unique_ptr is widely used in scenarios where resource management is critical. Here are a few common use cases:

  • Resource Management in Classes: Use unique_ptr to manage dynamically allocated members within a class, ensuring proper cleanup when the object is destroyed.
  • Factory Functions: When creating objects in factory methods, returning unique_ptr allows for safe ownership transfer while preventing memory leaks.
  • Data Structures: When implementing data structures like trees or graphs, unique_ptr can be used to manage child nodes, ensuring that the entire structure is cleaned up.

What's Next

Now that you have a solid grasp of unique_ptr and how it handles unique ownership of resources, you're ready to explore shared_ptr.

In the next chapter, we will discuss how shared_ptr allows multiple pointers to share ownership of the same resource, delving into its use cases and intricacies.