【发布时间】:2020-06-19 16:33:38
【问题描述】:
这是我编写的一些代码,只是为了了解如何使用指针。 这里我要分配并显示一个二维Pointerarray
int main()
{
constexpr int size = 10;
int** _2darray = new int* [size];
for ( int i = 0; i < size; i++ )
{
*(_2darray + i) = new int[i];
for ( int j = 0; j <= i; j++ )
{
*(*(_2darray + i) + j) = j;
}
}
for ( int i = 0; i < size; i++ )
{
for ( int j = 0; j <= i; j++ )
{
std::cout << _2darray[i][j] << " ";
}
std::cout << std::endl;
}
}
这将导致打印:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9
但如果我现在想防止内存泄漏,我想这样做:
for ( int i = 0; i < size; i++ )
{
delete[] _2darray[i];
}
delete[] _2darray;
不幸的是,这会给我一个堆损坏的异常
我猜它崩溃是因为它不知道子数组的确切大小,但我也听说 delete 总是跟踪为数组分配了多少字节。
感谢您的简短回答。
【问题讨论】:
-
删除逻辑正确。不幸的是,在创建数组之后和删除它们之前的某个时候,程序会越界并破坏存储在数组附近的一些重要的簿记信息。找出发生这种情况的地方,您就会解决问题。
-
当我看到一个带有
<=的循环时,我总是担心。检查由for ( int j = 0; j <= i; j++ )产生的j的范围,以确保它是您所期望的。 -
问题是
*(_2darray + i) = new int[i];,因为 for 循环是用 i=0 初始化的。您正在分配一个包含零项的数组,然后写入它 -
int** _2darray = new int* [size];分配给size指针。*(_2darray + i) = new int[i];分配给i int并依次将该块的起始地址分配给您的指针。当你想释放内存时,你必须首先循环你的指针释放分配的int块,然后再释放指针块。for (int i = 0; i < size; i++) delete[] _2darray[i];然后释放你的指针块,delete[] _2darray;。 (注意:不涉及“数组”,您已分配内存块)另请注意:_2darray[i]和_2darray[i][j]是可读的。 -
原来 j
标签: c++ arrays pointers memory dynamic