如何正确填充在堆上分配的二维数组?
How can I properly fill a 2D array that is allocated on the heap?
我在堆上创建了一个二维数组。我想用数字填充数组。我尝试了两种方法。第一次尝试有点工作,但问题是当我尝试删除它时程序会崩溃。我所做的第二次尝试可以在使用数组后将其删除,但数组未以正确的方式填充。
所以我是这样声明二维数组的:
int** matrix = new int*[rowSize];
for (int i = 0; i < rowSize; i++) {
matrix[i] = new int[ColSize];
}
然后我像这样填写它:
int matrixI0[]{1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1};
int matrixI1[]{1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1};
int matrixI2[]{1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1};
int matrixI3[]{1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1};
int matrixI4[]{1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1};
int matrixI5[]{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1};
int matrixI6[]{0, 0, 1, 0, 0, 0, 1, 1, 1, 0 ,0, 1};
matrix[0] = matrixI0;
matrix[1] = matrixI1;
matrix[2] = matrixI2;
matrix[3] = matrixI3;
matrix[4] = matrixI4;
matrix[5] = matrixI5;
matrix[6] = matrixI6;
当我以这种方式填充它时,数组的行为方式是我想要的,并且在使用该数组的后续方法中得到了预期的结果。
但是,当我尝试删除它时:
for (int i = 0; i < rowSize; ++i) {
delete[] matrix[i];
}
delete[] matrix;
我收到一个抛出的异常,其中包含以下错误消息"Test.exe 已触发断点。当然,如果我在发布中运行它,程序会崩溃。
我第二次尝试填充数组如下所示:
int matrixI0[]{1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1};
int matrixI1[]{1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1};
int matrixI2[]{1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1};
int matrixI3[]{1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1};
int matrixI4[]{1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1};
int matrixI5[]{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1};
int matrixI6[]{0, 0, 1, 0, 0, 0, 1, 1, 1, 0 ,0, 1};
matrix[0][0] = *matrixI0;
matrix[1][0] = *matrixI1;
matrix[2][0] = *matrixI2;
matrix[3][0] = *matrixI3;
matrix[4][0] = *matrixI4;
matrix[5][0] = *matrixI5;
matrix[6][0] = *matrixI6;
现在当我删除数组时没有问题,但现在数组的行为方式不是我想要的,当我测试使用该数组的方法时,我得到的结果与数组刚刚用零填充一样。
我知道我在第二次尝试中做得不对,但我只是这样做是为了看看必须做什么才能成功删除数组。
所以总结一下,我的问题是我应该如何以正确填充的方式填充二维数组,但它也会被成功删除?
谢谢!
快速回答:不要使用原始数组,这很C++,只需使用正确重载operator=
std::vector<int>/std::array<int>
,它们将为您完成工作,例如:
std::vector<std::vector<int>> matrix(7);
matrix[0] = { 1, 3, 3};
长答案:
您不是在堆上填充数组,而是将它们在matrix
中的引用替换为本地数组,这些数组在退出作用域时会被删除,并且在任何情况下都无法删除。
为了解释这个问题,让我们保持简单,假设堆上有单个数组
int* row = new int[rowSize];
所以你有一个变量行,它存储一个内存地址到堆上分配的数组:
| row | ------> |x|x|x|x|x|x|x|
现在你做了:
int myRow[] = { 1, 2, 3};
row = myRow;
发生的情况是,myRow
在堆栈上分配,其地址存储在变量row
最终导致如下情况:
| row | |x|x|x|x|x|x|x|
|
--> |y|y|y|y|y|y|y|
因此,您丢失了对堆上数组的任何引用,row
指向堆栈上的地址。您无法再删除row
,退出范围时,它指向的数据将成为垃圾。你最终没有复制任何东西。
要正确复制数据,您可以使用std::copy
,例如:
int myRow[] = { 1, 2, 3};
std::copy(myRow, myRow + rowSize, row);
<强制性的>强制性的>
让我们看看你对其中一个元素做了什么:
matrix[2] = new int[ColSize];
matrix[2]
(这是一个int*
(被赋予您在堆上分配的新数组的地址。
matrix[2] = matrixI2;
抛出旧的matrix[2]
值(指向堆上数组的指针(,导致旧的动态分配数组丢失,并将matrix[2]
指向本地数组,matrixI2
。
如果matrixI2
超出范围,则我们的指针现在无效。此外,没有必要delete matrix[2]
,因为它不指向动态分配的内存。
相反,你想要的可能是:
matrix[2] = new int[12]{1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1};
对于每个索引而不是循环。
- 如何正确填充在堆上分配的二维数组?
- 在 c++ 中分配布尔值的动态二维数组时超出内存限制
- 尝试从动态分配的二维数组 C++ 中读取值时出现分段错误,并在尝试删除它时给出 munmap_chunk():
- 在 C++ 中交叉动态分配的二维数组时的侵入性值/地址
- 如何将 50 行和 50 列的二维数组编码为一个为元素随机分配星号的函数?
- 程序终止,状态为 -1073741510 在 for 循环的中间,将输入分配给二维数组
- 为什么这个指针到指针的二维数组像这样分配新的 int
- 如何在C++中动态分配连续的二维数组?
- C 从嵌套循环中的文件中读取,并将值分配给二维数组
- 动态分配缓冲空间为二维数组 - 为什么失败
- 二维数组中的动态内存分配
- 从命令行输入分配二维数组
- 如何分配两个二维数组
- 二维数组分配中的内存管理
- 二维数组和分配对象
- 二维数组C++的动态分配
- 正确分配和取消分配指向对象的指针的二维数组
- 如何在C++中动态分配全局二维数组
- 如何在函数中分配二维数组
- 如何动态分配二维数组一行在一个时间,列是已知的在c/c++