-1

我有这个测试代码:

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'并发生错误,为什么?如何正确释放这样的数组?

4

2 回答 2

3

不要转换calloc()!的返回值


您正在为数组的每个元素分配相同的指针。我不知道你为什么/如何期望它工作(因为那样你就不会有一个类似二维的数组,因为设置一行的一个元素也会改变所有其他行中同一列的元素...... )

如果您仍然坚持这种设计,那么您应该只释放一次内部“数组”。

但我怀疑你想模仿一个理智的、有效的、合理的二维阵列。在这种情况下,您有两个选择:

I. hackish 解决方案:与您的几乎相同,但您需要calloc在单独的步骤中为每一行占用内存,如下所示:

twoDArray[0] = calloc(3, sizeof(twoDArray[0]));
twoDArray[1] = calloc(3, sizeof(twoDArray[0]));
twoDArray[2] = calloc(3, sizeof(twoDArray[0]));

(或者也许使用循环......如果你知道它们是什么。)

二、正确的解决方案:为什么不分配一个连续的内存块,避免所有多余的调用calloc()以及所有关于什么和什么时候需要被free()d 的头痛?一个数组 -> 一个分配,一个释放:

char (*arr[3]) = calloc(3, sizeof(arr[0]));

// ...

free(arr);

不错,简单且更易于维护。

于 2013-09-02T14:24:53.713 回答
0

如果你要创建freeArray函数,你必须定义一些关于数组必须包含什么的规则。您的实现freeArray假设数组的每个元素都指向一个单独分配的字符数组,但是数组的每个元素实际上都指向同一个字符数组,因此您最终尝试多次释放同一个数组,这是无效的。

如果freeArray的假设是正确的,那么您需要修改创建数组的方式。如果freeArray的假设不正确,则需要修改freeArray.

于 2013-09-02T14:28:17.720 回答