我有这个测试代码:
void test2(){
char** twoDArray = (char**)calloc(3,sizeof(char*));
char* element1 = (char*)calloc(3,sizeof(char));
twoDArray[0] = element1;
twoDArray[1] = element1;
twoDArray[2] = element1;
freeArray(twoDArray,3);
}
void freeArray(char** arr,int size){
if(arr!= NULL){
for(int i =0 ;i < size;i++){
if(arr[i] != NULL){
free(arr[i]);
arr[i] = NULL;
}
}
free(arr);
arr = NULL;
}
}
在freeArray
arr[1] != NULL
循环的第二次迭代中给出'true'并发生错误,为什么?如何正确释放这样的阵列?
答案 0 :(得分:3)
<强> Do not cast the return value of calloc()
! 强>
您正在为数组的每个元素指定相同的指针。我不知道为什么/你希望它如何工作(因为那样你就不会有类似2D的数组,因为设置一行的一个元素也会改变所有其他行中同一列的元素...... )
如果您仍然坚持这种设计,那么您应该只释放内部“阵列”一次。
但我怀疑你想要模仿理智,工作,明智的 2D阵列。在这种情况下,您有两个选择:
予。 hackish解决方案:几乎和你的一样,但是你需要calloc
在一个单独的步骤中为每一行记忆,如下所示:
twoDArray[0] = calloc(3, sizeof(twoDArray[0]));
twoDArray[1] = calloc(3, sizeof(twoDArray[0]));
twoDArray[2] = calloc(3, sizeof(twoDArray[0]));
(或者使用循环......如果你知道它们是什么。)
II。正确的解决方案:为什么不分配连续的内存块并避免对calloc()
的所有多余调用以及所有需要free()
d的问题?一个阵列 - &gt;一次分配,一次解除分配:
char (*arr[3]) = calloc(3, sizeof(arr[0]));
// ...
free(arr);
美观,简单,易于维护。
答案 1 :(得分:0)
如果要创建freeArray
函数,则必须定义一些有关数组必须包含的规则。您对freeArray
的实现假设数组的每个元素都指向一个单独分配的字符数组,但是数组的每个元素实际上都指向相同的字符数组,因此您最终会尝试释放多次使用相同的数组,这是无效的。
如果freeArray
的假设是正确的,那么您需要修改创建数组的方式。如果freeArray
的假设不正确,您需要修改freeArray
。