2016-11-16 19 views
39

Tôi luôn cảm thấy rằng std::unique_ptr không có chi phí nào so với việc sử dụng con trỏ thô. Tuy nhiên, biên dịch đoạn mã sauTại sao biên dịch instant_ptr biên dịch thành nhị phân lớn hơn con trỏ thô?

#include <memory> 

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

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

với g++ -std=c++14 -O3 sản xuất lắp ráp như sau:

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

Tại sao là đầu ra cho smart_pointer() gần gấp ba lần lớn như raw_pointer()?

+0

Nó có bộ đếm có liên quan và có thể là một chi phí nhỏ. Có lẽ một vtable –

+3

Tôi thực sự ngạc nhiên toàn bộ điều không được tối ưu hóa hoàn toàn đi. – SergeyA

+2

@SergeyA Với clang nó được. –

Trả lời

53

std::make_unique<int[]>(100) thực hiện value initialization khi new int[100] Thực hiện default initialization - Trong trường hợp đầu tiên, yếu tố được 0-khởi tạo (đối với int), trong khi ở các yếu tố trường hợp thứ hai bị bỏ uninitialized. Hãy thử:

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

Và bạn sẽ nhận được kết quả tương tự như với std::unique_ptr.

Xem this ví dụ, trong đó nêu rằng std::make_unique<int[]>(100) tương đương với:

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

Nếu bạn muốn có một mảng không khởi tạo với std::unique_ptr, bạn có thể sử dụng :

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

Như đã đề cập trong @Ruslan trong các nhận xét, hãy lưu ý về sự khác biệt đặt cược ween std::make_unique()std::unique_ptr() - Xem Differences between std::make_unique and std::unique_ptr.

+0

Tôi nghi ngờ rằng có thể là trường hợp. Có cách nào để tạo một 'unique_ptr' trỏ tới một mảng chưa được khởi tạo không? –

+2

@AlessandroPower 'std :: unique_ptr (int mới [100])'. – Holt

+3

@AlessandroPower nhưng hãy cẩn thận về [Sự khác biệt giữa std :: make_unique và std :: unique_ptr] (http://stackoverflow.com/q/22571202/673852). – Ruslan

Các vấn đề liên quan