使用std :: unique_ptr的双(二维)数组

Eva*_*van 10 c++ unique-ptr c++11

我有一个指针分配给指针的双数组.

  // pointer to pointer
  int **x = new int *[5];   // allocation
  for (i=0; i<5; i++){
      x[i] = new int[2];
  }

  for (i=0; i<5; i++){      // assignment
      for (j=0; j<2; j++){
          x[i][j] = i+j;
      }
  }

  for (i=0; i<5; i++)   // deallocation
      delete x[i];
  delete x;
Run Code Online (Sandbox Code Playgroud)

我试图这样做unique_ptr:

std::unique_ptr<std::unique_ptr<int>[]> a(new std::unique_ptr<int>[5]);
  for (i=0; i<5; i++)
      a[i] = new int[2];
Run Code Online (Sandbox Code Playgroud)

但一直都是这样说的错误no operator = matches these operands.我在这做错了什么?

Moo*_*uck 16

您无法将a分配int*给a std::unique_ptr<int[]>,这是导致错误的原因.正确的代码是

      a[i] = std::unique_ptr<int[]>(new int[2]);
Run Code Online (Sandbox Code Playgroud)

然而,piokuc是正确的,unique_ptr用于阵列是非常不寻常的,因为这是什么std::vectorstd::array适用,取决于是否提前知道大小.

//make a 5x2 dynamic jagged array, 100% resizable any time
std::vector<std::vector<int>> container1(5, std::vector<int>(2)); 
//make a 5x2 dynamic rectangular array, can resize the 5 but not the 2
std::vector<std::array<2, int>> container1(5); 
//make a 5x2 automatic array, can't resize the 2 or 5 but is _really fast_.
std::array<5, std::array<2, int>> container;
Run Code Online (Sandbox Code Playgroud)

所有这些都可以初始化并使用与您已有的代码相同,除非它们更容易构建,并且您不必销毁它们.

  • 当然,`std :: unique_ptr <int>(new int [2]);`将有错误的删除器 - 应该是`std :: unique_ptr <int []>(new int [2]);`.先发制人+1假设你会解决这个问题.; - ] (2认同)
  • @Evan:请务必对您认为有帮助的任何答案进行投票(使用左侧的向上箭头),并将其中一个标记为“正确”答案(在箭头下方使用复选标记)。 (2认同)

sak*_*kra 7

如果您没有使用a std::array或a std::vector而不是动态分配的数组,可以unique_ptr在C++ 11中使用a 作为二维数组,如下所示:

std::unique_ptr<int*, std::function<void(int**)>> x(
    new int*[10](),
    [](int** x) {
        std::for_each(x, x + 10, std::default_delete<int[]>());
        delete[] x;
    }
);
Run Code Online (Sandbox Code Playgroud)

unique_ptr声明需要分配的护理的阵列的尺寸.后()new int*[10]()确保每个列指针被初始化为nullptr.

然后for循环分配列数组:

for (size_t row = 0; row < 10; ++row) {
    (x.get())[row] = new int[5];
}
Run Code Online (Sandbox Code Playgroud)

unique_ptr超出范围时,其自定义删除器lambda函数负责在删除行数组之前删除列数组.该for_each表达式使用default_delete仿函数.


pio*_*kuc 2

您的代码正在有效地操作 int 数组的数组。

在 C++ 中,您通常希望将其实现为:

std::vector<std::vector<int> > x;
Run Code Online (Sandbox Code Playgroud)

这对于 来说不是一个好例子unique_ptr。此外,您不需要使用指向对象的指针unique_ptrunique_ptr动态分配对象。重点unique_ptr是消除指针的使用并提供对象的自动分配和释放。