推荐的方法使 std::unique_ptr 为数组类型而不进行值初始化?

dav*_*ewy 4 c++ memory-management smart-pointers unique-ptr

我有一些 C++ 代码,如下所示:

#include <memory>

void do_memory()
{
  std::unique_ptr<int[]> ptr = std::make_unique<int[]>(50);

  int* ptr2 = new int[50];
  delete[] ptr2;
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,我创建一个指向 int 数组的唯一指针,在第二种情况下,我分配一个原始 int 数组。当离开作用域时,两个数组都会被清理干净。玩弄这段代码(例如https://godbolt.org/g/c3gEfV),我发现这两组指令的优化汇编是不同的,因为make_unique执行值初始化(具体来说,它似乎设置了将数组分配给 0)。make_unique引入一些不必要的开销也是如此。

在不unique_ptr自动值初始化的情况下将 a 分配给数组(如上所示)的推荐方法是什么?我已经尝试过例如

std::unique_ptr<int[]> ptr = std::unique_ptr<int[]>(new int[50]);
Run Code Online (Sandbox Code Playgroud)

但在我的应用程序中,我也有一个限制,即我在编译时不知道数组的大小,因此我不想分配任何具有(编译时)常量大小的数组。

GMa*_*ckG 5

如果你确实必须这样做,只需编写你自己的函数:

template <typename T>
std::unique_ptr<T> make_unique_uninitialized(const std::size_t size) {
    return unique_ptr<T>(new typename std::remove_extent<T>::type[size]);
}
Run Code Online (Sandbox Code Playgroud)

避免直接创建的诱惑unique_ptr

std::unique_ptr<T[]>(new T[size])  // BAD
Run Code Online (Sandbox Code Playgroud)

因为这通常不是异常安全的(出于您make_unique首先使用的所有常见原因 - 考虑带有多个参数的函数调用和抛出的异常)。