2016-11-16 46 views
39

Her zaman bir std::unique_ptr'un bir ham işaretçiyi kullanmaya göre hiçbir yükü olmadığı izlenimi altındaydım. Ancak, g++ -std=c++14 -O3 ileNeden unique_ptr örnekleme ham pointer daha büyük ikili derler?

#include <memory> 

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

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

aşağıdaki montaj üreten aşağıdaki kodu derleme:

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

neden smart_pointer() neredeyse üç kat daha büyük raw_pointer() olarak için çıkış?

+0

Bir karşı tarafa ve belki de biraz daha fazla yükü var. Belki bir vtable –

+3

Aslında her şey tamamen uzak optimize edilmediği şaşırdım. clang ile – SergeyA

+2

@SergeyA öyle. –

cevap

53

std::make_unique<int[]>(100)value initializationnew int[100] ise gerçekleştirir default initialization gerçekleştirir için - 0-başlatılır (int için), ikinci kovan elemanları ise başlatılmamış bırakılır İlk durumda, elemanlar vardır.

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

Ve std::unique_ptr ile aynı çıktıyı alırsınız: deneyin. Eğer std::unique_ptr olmayan bir başlatıldı dizi istiyorsanız

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

şunu kullanabilirsiniz :

için std::make_unique<int[]>(100) denk olduğunu bildiren Örneğin, için this görün

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

@Ruslan tarafından belirtildiği gibi, yorumlarda farkın farkında olun. std::make_unique() ve std::unique_ptr() Ween - Differences between std::make_unique and std::unique_ptr bakınız.

+0

Bu durumdan şüphelenildi. Başlatılmamış bir diziye işaret eden bir 'unique_ptr 'oluşturmanın bir yolu var mı? –

+2

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

+3

@AlessandroPower ancak dikkat [Std :: make_unique ve std :: unique_ptr] arasındaki farklar (http://stackoverflow.com/q/22571202/673852). – Ruslan