2016-11-16 7 views
39

Zawsze miałem wrażenie, że std::unique_ptr nie ma narzutów w porównaniu do używania surowego wskaźnika. Jednak kompilacji następujący kodDlaczego unikatowa instancja kompiluje się do większego binarnego niż surowy wskaźnik?

#include <memory> 

void raw_pointer() { 
    int* p = new int[100]; 
    delete[] p; 
} 

void smart_pointer() { 
    auto p = std::make_unique<int[]>(100); 
} 

z g++ -std=c++14 -O3 produkuje następujący montaż:

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*) 

Dlaczego jest wyjście dla smart_pointer() prawie trzy razy większy raw_pointer()?

+0

Ma licznik i może trochę narzut. Być może vtable –

+3

Jestem rzeczywiście zaskoczony, że całość nie jest w ogóle zoptymalizowana. – SergeyA

+2

@SergeyA Z clang to jest. –

Odpowiedz

53

Ponieważ std::make_unique<int[]>(100) wykonuje value initialization while new int[100] Wykonuje default initialization - w pierwszym przypadku elementy 0 inicjalizacji (na int), podczas gdy w drugim przypadku elementów pozostaje zainicjalizowana. Wypróbuj:

int *p = new int[100](); 

Otrzymasz te same wyniki, co w przypadku modelu std::unique_ptr.

Zobacz this na przykład, w którym stwierdza, że ​​std::make_unique<int[]>(100) odpowiada:

std::unique_ptr<T>(new int[100]()) 

Jeśli chcesz niezainicjalizowany tablicę z std::unique_ptr, można użyć :

std::unique_ptr<int[]>(new int[100]); 

Jak wspomniano przez @Ruslan w komentarzach, należy pamiętać o zakładzie różnicy ween std::make_unique() i std::unique_ptr() - Zobacz Differences between std::make_unique and std::unique_ptr.

+0

Podejrzewałem, że tak być może. Czy istnieje sposób na utworzenie 'unique_ptr' wskazującego niezainicjowaną tablicę? –

+2

@AlessandroPower 'std :: unique_ptr (nowy int [100])'. – Holt

+3

@Alessandroower, ale uwaga na [Różnice między std :: make_unique i std :: unique_ptr] (http://stackoverflow.com/q/22571202/673852). – Ruslan

Powiązane problemy