← Back to C++ Course | Chapter 14: Memory Management | Lesson 5 of 6

C++ unique_ptr

A unique_ptr is a smart pointer that owns one thing alone and cleans it up automatically, like the only key to a locker. You can pass it on, but not copy it.
Syntax
cpp
#include <memory>

std::unique_ptr<data_type> pointer_name = std::make_unique<data_type>(value);
std::unique_ptr<data_type> other = std::move(pointer_name);  // transfer ownership

What is unique_ptr?

std::unique_ptr, introduced in C++11, wraps a raw pointer and guarantees that exactly one owner exists for the object at any time.

When the unique_ptr variable goes out of scope, its destructor automatically calls delete on the managed object, so you never have to remember to free it manually.

Example: What is unique_ptr?

cpp
// Include std::cout and std::cin
#include <iostream>
// Include smart pointers
#include <memory>

// Program execution starts in main()
int main() {
	// Use a unique_ptr: a smart pointer that owns the object and frees it automatically
	std::unique_ptr<int> ptr(new int(42));
	// Print to the console with cout
	std::cout << *ptr << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

No Copying, Only Moving

Because a unique_ptr represents exclusive ownership, its copy constructor is deleted -- attempting to copy one is a compile error.

To hand ownership to another unique_ptr, you must explicitly std::move it, which transfers the underlying pointer and leaves the original empty rather than duplicating access.

Example: No Copying, Only Moving

cpp
// Include std::cout and std::cin
#include <iostream>
// Include smart pointers
#include <memory>

// Program execution starts in main()
int main() {
	// Use a unique_ptr: a smart pointer that owns the object and frees it automatically
	std::unique_ptr<int> ptr1(new int(5));
	// Use a unique_ptr: a smart pointer that owns the object and frees it automatically
	std::unique_ptr<int> ptr2 = std::move(ptr1);
	// Print to the console with cout
	std::cout << *ptr2 << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

reset() and release()

Calling reset() immediately deletes the currently owned object and optionally starts managing a new one you pass in.

Calling release() instead hands back the raw pointer to you and forgets about it entirely, so you become responsible for deleting it manually -- useful when interfacing with older APIs that expect raw pointers.

Example: reset() and release()

cpp
// Include std::cout and std::cin
#include <iostream>
// Include smart pointers
#include <memory>

// Program execution starts in main()
int main() {
	// Use a unique_ptr: a smart pointer that owns the object and frees it automatically
	std::unique_ptr<int> ptr(new int(5));
	// Allocate an object on the heap with new
	ptr.reset(new int(10));
	// Print to the console with cout
	std::cout << *ptr << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

unique_ptr with Arrays

For dynamically allocated arrays, declare unique_ptr<T[]> rather than unique_ptr<T> -- this specialization overloads operator[] for element access and automatically calls delete[] instead of delete when it goes out of scope, matching how the array was originally allocated.

Example: unique_ptr with Arrays

cpp
// Include std::cout and std::cin
#include <iostream>
// Include smart pointers
#include <memory>

// Program execution starts in main()
int main() {
	// Use a unique_ptr: a smart pointer that owns the object and frees it automatically
	std::unique_ptr<int[]> arr(new int[3]{1, 2, 3});
	// Print to the console with cout
	std::cout << arr[1] << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

make_unique (C++14)

std::make_unique<T>(args) is the recommended way to create a unique_ptr, since it constructs the object and wraps it in one expression -- avoiding a bare new that could leak memory if an exception were thrown between allocation and wrapping.

It was added in C++14 to match make_shared, which existed since C++11.

Example: make_unique (C++14)

cpp
// Include std::cout and std::cin
#include <iostream>
// Include smart pointers
#include <memory>

// Program execution starts in main()
int main() {
	// Use a unique_ptr: a smart pointer that owns the object and frees it automatically
	auto ptr = std::make_unique<int>(99);
	// Print to the console with cout
	std::cout << *ptr << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Copying a unique_ptr, which does not compile; use std::move to transfer ownership.
  2. Using the pointer after release() without taking care of freeing it.
  3. Creating a unique_ptr from a raw pointer that another owner also deletes.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.