为什么unique_ptr实例化编译为比原始指针更大的二进制?

时间:2016-11-16 14:49:01

标签: c++ assembly smart-pointers

与使用原始指针相比,我始终认为std::unique_ptr没有任何开销。但是,编译以下代码

#include <memory>

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

void smart_pointer() {
  auto p = std::make_unique<int[]>(100);
}
带有g++ -std=c++14 -O3

会生成以下程序集:

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

为什么smart_pointer()的输出几乎是raw_pointer()的三倍?

1 个答案:

答案 0 :(得分:54)

因为std::make_unique<int[]>(100)执行value initializationnew int[100]执行default initialization - 在第一种情况下,元素是0初始化(对于int),而在第二个案例元素未初始化。尝试:

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

您将获得与std::unique_ptr相同的输出。

例如,请参阅this,其中指出std::make_unique<int[]>(100)等同于:

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

如果你想要一个带有std::unique_ptr的非初始化数组,你可以使用 1

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

1 正如评论中@Ruslan所述,请注意std::make_unique()std::unique_ptr()之间的区别 - 请参阅Differences between std::make_unique and std::unique_ptr