I was always under the impression that a std::unique_ptr
had no overhead compared to using a raw pointer. However, compiling the following code
#include <memory> void raw_pointer() { int* p = new int[100]; delete[] p; } void smart_pointer() { auto p = std::make_unique<int[]>(100); }
with g++ -std=c++14 -O3
produces the following assembly:
raw_pointer(): sub rsp, 8 mov edi, 400 call operator new[](unsigned long) add rsp, 8 mov rdi, rax jmp operator delete[](void*) smart_pointer(): sub rsp, 8 mov edi, 400 call operator new[](unsigned long) lea rdi, [rax+8] mov rcx, rax mov QWORD PTR [rax], 0 mov QWORD PTR [rax+392], 0 mov rdx, rax xor eax, eax and rdi, -8 sub rcx, rdi add ecx, 400 shr ecx, 3 rep stosq mov rdi, rdx add rsp, 8 jmp operator delete[](void*)
Why is the output for smart_pointer()
almost three times as large as raw_pointer()
?
After move , unique_ptr s are set to nullptr .
Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.
Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
A std::unique_ptr owns of the object it points to and no other smart pointers can point to it. When the std::unique_ptr goes out of scope, the object is deleted. This is useful when you are working with a temporary, dynamically-allocated resource that can get destroyed once out of scope.
Because std::make_unique<int[]>(100)
performs value initialization while new int[100]
performs default initialization - In the first case, elements are 0-initialized (for int
), while in the second case elements are left uninitialized. Try:
int *p = new int[100]();
And you'll get the same output as with the std::unique_ptr
.
See this for instance, which states that std::make_unique<int[]>(100)
is equivalent to:
std::unique_ptr<T>(new int[100]())
If you want a non-initialized array with std::unique_ptr
, you could use1:
std::unique_ptr<int[]>(new int[100]);
1 As mentioned by @Ruslan in the comments, be aware of the difference between std::make_unique()
and std::unique_ptr()
- See Differences between std::make_unique and std::unique_ptr.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With