哪个更好:一个unique_ptr到一个2D阵列,还是一个unique _ptr的2D阵列

Which would be better: A unique_ptr to a 2D array or a 2D array of unique_ptrs?

本文关键字:一个 2D 阵列 unique ptr 更好      更新时间:2023-10-16

我目前正在制作一个旧的内存安全项目。

在这个项目中,我有一个2D数组,其中填充了指向我自己的类Block实例的指针。

这样声明:

Block* gemGrid[xMax][yMax];

然后像这样填充:

for(int i = 0; i<8; i++)
{
    for(int j = 0; j<8; j++)
    {
        //do stuff here
        gemGrid[i][j] = new Block(i,j, gridOffset);
    }
}

这很好用。

我有了创建unique_ptr<Block>的2D阵列而不是Block*的想法。

我决定这样声明:

unique_ptr<Block> gemGrid[xMax][yMax];

并像这样填充:

for(int i = 0; i<8; i++)
{
    for(int j = 0; j<8; j++)
    {
        gemGrid[i][j].reset( new Block(i,j, gridOffset));
    }
}

然而,当我尝试这样做时,编译器决定完全忽略第二个for循环("j"递增的部分),只创建一个一维数组。

这让我想问,C++在2D阵列中与unique_ptrs有问题吗?我应该只使用指向Blocks的指针的2D数组,并使用一个unique_ptr来确保这个数组在超出范围时被杀死吗?

C++对unique_ptr的二维数组没有任何异议。

你提供的两个替代方案对我来说似乎不是真正的替代方案。如果你有一个unique_ptrBlock*的二维数组,并且你使用new分配BlockxMax * yMax实例,并将指向它们的指针存储在数组中,那么谁或什么将释放Block的这些实例?unique_ptr当然不是。因此,"我应该这么做吗"的答案几乎肯定是"不",因为你会有内存泄漏。

分配Block实例的二维布局的最"明显"的方法是定义Block的二维数组(使用内置数组或std::array(如果可用))。如果你能识别出任何不适合你的东西,那么有人可以为你的旧代码提出一种替代方法,以避免内存泄漏。

[回应上面的评论]完成Block gemGrid[xMax][yMax];后,如果需要的话,可以获得一个指向Block对象的指针,如下所示:&gemGrid[i][j]。需要一个指针与内存分配完全无关。指针new允许您访问其分配的对象的方法,但无论如何分配,您都可以将指针指向对象。