Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does unique_ptr instantiation compile to larger binary than raw pointer?

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()?

like image 907
Alessandro Power Avatar asked Nov 16 '16 14:11

Alessandro Power


People also ask

What happens to unique_ptr after move?

After move , unique_ptr s are set to nullptr .

When should we use unique_ptr?

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.

In what situation is a shared_ptr more appropriate than a unique_ptr?

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.

What happens when unique_ptr goes out of scope?

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.


1 Answers

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.

like image 116
Holt Avatar answered Oct 17 '22 02:10

Holt