1

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

在这个项目中,我有一个 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>而不是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++有问题吗?unique_ptrs我是否应该坚持使用指向Blocks 的 2D 指针数组,并unique_ptr确保该数组超出范围时被杀死?

4

1 回答 1

4

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

你提供的两种选择对我来说似乎不是真正的选择。如果您有一个unique_ptr的二维数组Block*,并且您分配了usingxMax * yMax的实例并将指向它们的指针存储在您的数组中,那么谁或什么将释放这些实例?当然不是。所以“我应该这样做”的答案几乎肯定是“不”,因为你会有内存泄漏。BlocknewBlockunique_ptr

分配 2-D 实例布局的最“明显”方式Block是定义 2-D 数组Block(使用内置数组或std::array如果可用)。如果您可以识别出任何不适合您的内容,那么有人可以为您的旧代码建议一种替代方法以避免内存泄漏。

[回应上述评论] 完成Block gemGrid[xMax][yMax];后,如果需要,您可以获得指向您的 Block 对象之一的指针,如下所示:&gemGrid[i][j]. 需要指针与内存分配完全无关。指针允许您访问它分配的对象的方法new,但是您可以获取指向对象的指针,而不管它是如何分配的。

于 2013-02-05T14:40:14.253 回答