0
0
CppHow-ToBeginner · 3 min read

How to Use unique_ptr in C++: Syntax and Examples

Use std::unique_ptr in C++ to manage dynamic memory automatically by owning a pointer exclusively. It deletes the object when the unique_ptr goes out of scope, preventing memory leaks.
📐

Syntax

The std::unique_ptr is a smart pointer that owns a dynamically allocated object exclusively. It is declared as std::unique_ptr<Type> ptr;. You can initialize it with std::make_unique<Type>() or by passing a raw pointer. When the unique_ptr is destroyed, it automatically deletes the owned object.

Key parts:

  • Type: The type of the object to manage.
  • std::make_unique<Type>(): Safely creates a new object and returns a unique_ptr.
  • ptr.get(): Access the raw pointer without transferring ownership.
  • ptr.release(): Releases ownership and returns the raw pointer.
cpp
std::unique_ptr<Type> ptr = std::make_unique<Type>(constructor_args);
💻

Example

This example shows how to create a unique_ptr to manage a dynamically allocated integer. It prints the value and automatically frees memory when the pointer goes out of scope.

cpp
#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> ptr = std::make_unique<int>(42); // create unique_ptr managing int 42
    std::cout << "Value: " << *ptr << std::endl; // access the value
    // No need to delete ptr, it is automatic
    return 0;
}
Output
Value: 42
⚠️

Common Pitfalls

Common mistakes when using unique_ptr include:

  • Trying to copy a unique_ptr (copying is not allowed because ownership is unique).
  • Using raw pointers after releasing ownership without proper deletion.
  • Not using std::make_unique which is safer than using new directly.

Correct way to transfer ownership is using std::move.

cpp
#include <memory>
#include <iostream>

int main() {
    std::unique_ptr<int> ptr1 = std::make_unique<int>(10);
    // std::unique_ptr<int> ptr2 = ptr1; // Error: copy not allowed

    std::unique_ptr<int> ptr2 = std::move(ptr1); // Correct: transfer ownership
    if (!ptr1) {
        std::cout << "ptr1 is now empty after move." << std::endl;
    }
    std::cout << "ptr2 value: " << *ptr2 << std::endl;
    return 0;
}
Output
ptr1 is now empty after move. ptr2 value: 10
📊

Quick Reference

OperationDescriptionExample
Create unique_ptrCreate and own a new objectauto ptr = std::make_unique(5);
Access objectUse * or -> to access the object*ptr or ptr->member
Transfer ownershipMove ownership to another unique_ptrauto ptr2 = std::move(ptr1);
Release ownershipRelease pointer without deletingint* raw = ptr.release();
Reset pointerDelete current object and set to newptr.reset(new int(10));

Key Takeaways

Use std::unique_ptr to automatically manage dynamic memory with exclusive ownership.
Always prefer std::make_unique to create unique_ptr safely.
You cannot copy unique_ptr; use std::move to transfer ownership.
unique_ptr deletes the owned object automatically when it goes out of scope.
Avoid using raw pointers from unique_ptr without careful ownership handling.