The Palos Publishing Company

Follow Us On The X Platform @PalosPublishing
Categories We Write About

How to Use std__make_shared to Minimize Memory Overhead

std::make_shared is a function in C++ introduced in C++11 that allows you to create a shared pointer with a minimal overhead. It is an efficient way to manage dynamic memory allocation, and it’s often preferred over using new directly when creating shared pointers. By utilizing std::make_shared, you can reduce memory overhead, improve performance, and ensure better exception safety.

What is std::make_shared?

std::make_shared is a factory function provided by the C++ Standard Library that creates a std::shared_ptr while also allocating the memory for the managed object in a single, unified block. This is in contrast to manually allocating memory for an object and then creating a std::shared_ptr using new. The function combines both allocations (the object and the control block) into one efficient operation.

The syntax of std::make_shared is:

cpp
std::shared_ptr<T> ptr = std::make_shared<T>(args...);

Where T is the type of the object you’re creating, and args... are the arguments passed to the constructor of T.

The Problem with new and shared_ptr

When using new to create an object and then creating a shared_ptr like so:

cpp
std::shared_ptr<T> ptr = std::shared_ptr<T>(new T(args...));

There are two separate memory allocations happening:

  1. Memory for the object (new T(args...)).

  2. Memory for the reference count control block (inside the shared_ptr).

This dual allocation can lead to additional overhead, especially when you’re working with many shared pointers in a program.

How std::make_shared Reduces Memory Overhead

When you use std::make_shared, both the object and the reference count control block are allocated together in a single memory block. This combined allocation reduces memory fragmentation and improves cache locality, as both the object and the control block are next to each other in memory. It eliminates the need for two allocations and one deallocation, resulting in less overhead.

For example:

cpp
std::shared_ptr<T> ptr = std::make_shared<T>(args...);

In this case, only one memory allocation is made: one block for both the object and the reference-count control block.

Benefits of std::make_shared

  1. Reduced Memory Allocations: As mentioned, std::make_shared only requires one memory allocation, as opposed to using new which requires two (one for the object and one for the control block).

  2. Improved Performance: Fewer allocations and deallocations generally lead to improved performance, especially in memory-intensive applications where many shared pointers are created and destroyed.

  3. Better Cache Locality: Because the object and the reference control block are allocated together, accessing them is often faster due to improved cache locality.

  4. Exception Safety: std::make_shared provides better exception safety than manually using new. If an exception is thrown during the creation of the object, no memory will be leaked, since std::make_shared ensures that the memory is properly freed, even in the event of an exception.

  5. Cleaner Syntax: std::make_shared provides a cleaner and more intuitive syntax than manually creating the shared pointer, improving code readability.

Comparison with std::shared_ptr Constructor

Here’s a comparison between using std::shared_ptr with new and using std::make_shared.

  1. Using new with std::shared_ptr:

cpp
std::shared_ptr<T> ptr = std::shared_ptr<T>(new T(args...));
  • Allocations: Two separate memory allocations (one for the object and one for the control block).

  • Memory management: The object and control block are allocated separately, which can cause memory fragmentation.

  • Performance: Can incur a performance penalty due to two allocations and one deallocation.

  1. Using std::make_shared:

cpp
std::shared_ptr<T> ptr = std::make_shared<T>(args...);
  • Allocations: One combined memory allocation for both the object and the control block.

  • Memory management: More efficient and avoids fragmentation.

  • Performance: Typically performs better than using new due to reduced allocations.

When Should You Use std::make_shared?

You should generally use std::make_shared in most situations where you would use std::shared_ptr. The primary exceptions are cases where:

  1. You need a shared_ptr that is not constructed from new: If you need to create a shared_ptr for an object that was allocated in a different way (for example, via a custom memory allocator), you can still use std::shared_ptr directly, but std::make_shared won’t be applicable.

  2. For non-trivial objects with custom deleters: If you need a custom deleter or have non-trivial resource management that requires additional logic beyond memory management, you may need to create the shared_ptr explicitly, though this is rare.

Example: Using std::make_shared

Consider a simple example of a std::shared_ptr managing an object of class Foo:

cpp
#include <iostream> #include <memory> class Foo { public: Foo(int val) : value(val) { std::cout << "Foo constructor: " << value << std::endl; } ~Foo() { std::cout << "Foo destructor: " << value << std::endl; } int value; }; int main() { std::shared_ptr<Foo> ptr = std::make_shared<Foo>(42); std::cout << "Value: " << ptr->value << std::endl; return 0; }

Output:

yaml
Foo constructor: 42 Value: 42 Foo destructor: 42

In this case, the std::shared_ptr is created using std::make_shared, and it manages the Foo object efficiently.

Conclusion

std::make_shared is a powerful tool that minimizes memory overhead by combining the allocation of both the object and its control block. It enhances performance, reduces memory fragmentation, and provides better exception safety compared to manually allocating objects with new. By using std::make_shared, you can write cleaner, more efficient, and more reliable C++ code.

Share this Page your favorite way: Click any app below to share.

Enter your email below to join The Palos Publishing Company Email List

We respect your email privacy

Categories We Write About