我在堆上创建了一个二维数组。我想用数字填充数组。我尝试了两种方法。第一次尝试是可行的,但是问题是,当我尝试删除程序时,该程序将崩溃。使用后的第二次尝试使删除数组成为可能,但数组未正确填充。
这就是我声明二维数组的方式:
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;
现在,当我删除数组时没有问题,但是现在数组没有表现出我想要的方式,当我测试使用数组的方法时,我得到的结果与数组会得到的结果相同只是已经充满了零。
我知道我在第二次尝试中操作不正确,但是我只是这样做是为了查看必须执行的操作才能成功删除数组。
因此,总而言之,我的问题是我应该如何以正确填充二维数组的方式填充二维数组,但它也会成功删除?
谢谢!
答案 0 :(得分:2)
快速答案:不要使用原始数组,它是C ++,只需使用std::vector<int>/std::array<int>
即可适当地重载operator=
,它们将为您完成工作,例如:< / p>
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);
答案 1 :(得分:2)
<强制性的“您应该使用2D std :: vector代替!”咆哮(不,但实际上,如果您只是使用向量,所有这些操作都会更容易)>
让我们看看您正在为以下元素之一做什么:
matrix[2] = new int[ColSize];
为 matrix[2]
(即int*
)提供了您在堆上分配的新数组的地址。
matrix[2] = matrixI2;
丢弃旧值matrix[2]
(指向堆上数组的指针),导致旧的动态分配数组丢失,并将matrix[2]
指向本地数组{{1 }}。
如果matrixI2
超出范围,则我们的指针现在无效。此外,由于它没有指向动态分配的内存,因此无需matrixI2
。
相反,您想要的可能是:
delete matrix[2]
每个索引而不是循环。