In Modern C++, we can create unique_ptr object to manage dynamically allocated arrays. However, the syntax for using std::unique_ptr
with arrays is a bit different. In this article, we will look into this in more detail.
Syntax to use unique_ptr with Arrays
When you want a create a unique_ptr object to manage a dynamically allocated array, you need to indicate that the unique pointer is pointing to an array. Here’s how you can do it:
Using new operator with unique_ptr
#include <iostream> #include <memory> int main() { auto arr = std::unique_ptr<int[]>(new int[6]{67, 78, 16, 26, 98, 63}); // Use the unique pointer array for (int i = 0; i < 6; ++i) { std::cout << arr[i] << " "; } std::cout << std::endl; return 0; }
Output:
67 78 16 26 98 63
In this example, we’ve created a std::unique_ptr
that manages an array of 6 integers. Note that when you use new
to allocate an array, you must follow the type with square brackets []
. This tells the unique pointer that it’s managing an array, not a single object. Once allocated, you can use the unique pointer to access elements in the array just like a regular array.
When you manage dynamic arrays in C++, it’s crucial to ensure that the allocated memory is properly deallocated. In traditional C++ without smart pointers, you’d allocate an array with new[]
and deallocate it with delete[]
. The delete[]
operator is used to destroy array elements and release memory that was allocated for the array with new[]
.
However, when using std::unique_ptr
with arrays, you don’t need to (and shouldn’t) use delete[]
directly. The unique pointer takes care of memory management for you. It’s one of the key features of smart pointers in modern C++: they automatically deal with releasing memory when they go out of scope, which includes calling delete[]
for arrays.
Using unique_ptr with Arrays
C++14 introduced std::make_unique
, which provides a safer alternative to using new
directly. Here’s how you would use it for arrays:
#include <iostream> #include <memory> int main() { auto arr = std::make_unique<int[]>(3); // Initialize elements (not directly via make_unique due to limitations) for (int i = 0; i < 3; ++i) { arr[i] = (i + 1) * 100; } // Iterate over the array elements & Print them for (int i = 0; i < 3; ++i) { std::cout << arr[i] << " "; } std::cout << std::endl; return 0; }
Output:
100 200 300
Important Points to Remember:
- Array Type Indication: When using a unique pointer to manage an array, the type declaration must include
[]
to indicate that it is an array type. - Auto Deduction: The
auto
keyword can be used for type deduction to simplify the syntax when declaring a unique pointer for an array. - Accessing Elements: Access elements of a unique pointer array using the subscript operator
[]
just like a regular array. - Safe Memory Management: Just like with single objects,
std::unique_ptr
for arrays ensures that the allocated memory is automatically and safely deallocated when the unique pointer goes out of scope. - Initialization Limitations: Directly initializing array elements during allocation with
std::make_unique
isn’t supported. You must initialize elements after allocation.
Summary
We can use the unique_ptr with Arrays safely for automatic memory management in C++.