对于即将到来的中期,我们的一个练习问题是编写一个函数,它将删除一个二维的int数组并将指针设置为NULL。我以为我知道怎么做这个但是班上的其他人说了一些让我很困惑的东西(他们说我们应该使用三指针以便我们可以修改数组,但是数组本身不是一个指针吗?那么**数组不会等同于三重指针吗?)。我的功能是否正确?
void cleanUp(int** array, int numRows, int numCols) {
for (int i = 0; i < numRows; ++i) {
free((*array)[i]);
}
free(*array);
*array = NULL;
}
答案 0 :(得分:1)
您将首先删除所有单独的行(包含int
),然后将删除int*
的大块。
void cleanUp(int** array, int numRows, int numCols) {
for (int i = 0; i < numRows; ++i) {
free(array[i]); // deleting the individual arrays
}
free(array); // deleting array of `int*`
}
如果是锯齿状数组,free
- 与你分配完整锯齿状数组的方式相反。
首先为numRow
int*
分配空间。
然后,对于每个int*
,您将分配numCol
int
。
现在你做的与你所做的完全相反:
首先删除所有int
。
然后执行int*
。
这种排序的原因是如果你先删除int*
- s,那么就会出现内存泄漏。在丢失对它的引用的同时,你不会释放用于存储int
的内存空间。这就是解除分配内存的相反顺序的原因。
答案 1 :(得分:1)
如果你还需要将指针设置为NULL,那么肯定你需要在函数中使用int ***
参数,并将它传递给你要清理的指针变量的地址。
void cleanUp(int*** parray, int numRows, int numCols) {
int **array = *parray;
for (int i = 0; i < numRows; ++i) {
free(array[i]);
}
free(array);
*parray = NULL;
}
请注意numCols
未被使用,因此可以删除,除非您需要将其用于进一步清理。
为了解释用法,假设有一个变量int **thearray;
已经设置为指向动态分配的int *
数组({1}}元素的{第一个元素}很长,并且numRows
,thearray[0]
,...,thearray[1]
中的每一个都已设置为指向动态分配的thearray[numRows - 1]
数组(的第一个元素)这是int
个元素。然后调用numCols
将释放cleanUp(&thearray);
的每一行(由int
,...,thearray[0]
指向),释放thearray[numRows - 1]
的数组( int *
变量指出的内容,并将thearray
变量本身设置为thearray
。该函数不知道NULL
变量,但其thearray
参数指向它,因此可以间接将其设置为parray
。
答案 2 :(得分:0)
这也是内存对齐的问题。如果计算propper偏移量,您可以将int(int *)的线性序列解释为2D,3D或n-D数组。所以没有必要使用三指针。指针没有直接映射到数组,但每个数组变量都是指向第一个值的指针(或嵌套数组的指针值)。