我目前正在制作一个安全的旧项目。
在这个项目中,我有一个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++
在2D数组中遇到unique_ptrs
问题了吗?我应该坚持使用指向Block
s的2D数组,并且有一个unique_ptr
确保该数组在超出范围时被终止?
答案 0 :(得分:4)
C ++对unique_ptr
的二维数组无异议。
您提供的两种选择似乎不是我的真正替代品。如果unique_ptr
到Block*
的二维数组,并使用xMax * yMax
分配Block
个new
个实例,并将指针存储在您的Block
中数组,那么谁或什么将释放unique_ptr
的那些实例?当然Block
不是。因此,“我应该这样做”的答案几乎肯定是“不”,因为你会有内存泄漏。
分配Block
实例的二维布局最“明显”的方法是定义std::array
的二维数组(使用内置数组或Block gemGrid[xMax][yMax];
如果可供使用的话)。如果您能够识别出任何不适合您的内容,那么有人可以为您的旧代码建议一种替代方法,以避免内存泄漏。
[回复上面的评论]完成&gemGrid[i][j]
后,您可以获得指向其中一个Block对象的指针(如果需要),如下所示:new
。需要指针与内存分配完全无关。指针是 {{1}}允许您访问其分配的对象的方式,但您可以获取指向对象的指针,而不管它是如何分配的。