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

标签 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() 的三倍?

最佳答案

因为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 .

关于c++ - 为什么 unique_ptr 实例化编译为比原始指针更大的二进制文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40635107/

相关文章:

c++ - strcpy 不适用于相同大小的数组

c - ARM 程序集使用 C 调用以寄存器作为参数的函数

assembly - 我正在使用 BPX1WRT 编写我的 hello-world HL/ASM 程序,但它失败了,因为它不可重入

c++ - Const 与 C++ 中的智能指针

c++ - 包含 unique_ptr 的 unordered_map 的对象的深拷贝

c++ - vector 的 std::remove 和删除之间的区别?

c++ - 如何将 shared_ptr 传递给生命周期较短的类?

c# - 函数的 IDL 声明(在 C++ 中)将从 C# 获取 C 样式数组

c - 将生成的程序集重写为 GCC 内联汇编

c++ - 当作为引用给出时, std::unique_ptr 是否会在作用域之后自动清理?