Smart Pointers and std::unique_ptr

std::make_unique vs new Keyword

What are the advantages of using std::make_unique over the new keyword?

Illustration representing computer hardware

std::make_unique, introduced in C++14, is generally preferred over using the new keyword directly when creating a std::unique_ptr. Here are several reasons why:

Exception Safety

If you use new and then pass the raw pointer to the unique_ptr constructor, there's a risk of a memory leak if an exception is thrown before the unique_ptr takes ownership. std::make_unique avoids this by constructing the object directly in the unique_ptr.

Consider this example:

#include <memory>
#include <iostream>

void SomeFunction() {
  std::unique_ptr<int> p{new int{0}};
  throw std::exception{};  
}

int main() {
  try {
    SomeFunction();
  } catch (...) {
    std::cout << "Caught exception, but "
      "possibly leaked memory";
  }
}
Caught exception, but possibly leaked memory

If an exception is thrown after the new int{0} but before the unique_ptr constructor, the memory will leak. Now consider the same example with make_unique:

#include <memory>
#include <iostream>

void SomeFunction() {
  std::unique_ptr<int> p{
    std::make_unique<int>(0)};
  throw std::exception{};
}

int main() {
  try {
    SomeFunction();
  } catch (...) {
    std::cout << "Caught exception, "
      "without leaking memory";
  }
}
Caught exception, without leaking memory

Here, if an exception is thrown, the unique_ptr will still properly clean up the memory.

Readability

std::make_unique makes it clear that the intent is to create a unique_ptr. It's a more expressive way to create a smart pointer.

Consistency

std::make_unique provides consistency with std::make_shared, which is the recommended way to create a std::shared_ptr.

Less typing

While not a major advantage, std::make_unique does save you from typing out the template argument twice:

// With new
std::unique_ptr<Character> Gandalf{
  new Character{"Gandalf"}};

// With make_unique
auto Gandalf{std::make_unique<Character>(
  "Gandalf")};

There are a few situations where you might still use new with unique_ptr:

  • If you need to specify a custom deleter
  • If you're working with C++11 (although you can implement your own make_unique for C++11)

But in most cases, std::make_unique is the preferred way to create a std::unique_ptr.

Answers to questions are automatically generated and may not have been reviewed.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved