繁体   English   中英

免费的2D阵列列

[英]Free 2D array columns

我有一个二维的字符串数组,它是动态分配的:

char*** allocateArray(int line, int col)
{
    char*** dictionary;
    int i=0,j=0;
    dictionary=(char***)malloc(sizeof(char**)*line);
    for(i=0;i<line;i++)
    {
        dictionary[i] = (char**)malloc(sizeof(char*));
        for(j=0;j<col;j++)
            dictionary[i][j] = (char*)malloc(sizeof(char*));
    }
    return dictionary;
}

现在我想释放最后一列(可以说),我该怎么办? 我使用free(dictionary[i][j]) ,但是实际上是什么呢? 数组中的[i][j]单元格或其指向的指针? 我都需要释放。

dictionary[i][j] = (char*)malloc(sizeof(char*)); 是错误的,您要为char而不是char *分配空间。 您将像释放其他任何指针一样释放它,因此free(dictionary[i][j])是正确的。

请记住,您必须按照与保留内存相反的顺序释放内存。 在这种情况下,循环j以释放出dictionary[i][j] (其中索引i是固定的)是正确的,因为那样的话,您将释放为*(*(dictionary + i) + j) 之后,您将遍历i以释放dictionary[i] (这将释放为* (dictionary + i )保留的空间,最后,您将只free (dictionary) (并且您正在释放* dictionary )。

注意:释放空间的顺序很重要,因为如果您释放实际上指向另一个保留内存块的内存块,那么您将无法再释放最后一个内存块,因此会发生内存泄漏。 这就是为什么您必须以相反的顺序(称为malloc开始释放内存。

总结一下,这段代码可以很好地在您的代码中正常工作(我在Valgrind上进行了测试,并且没有内存泄漏):

for (i = 0; i < line; i++){
    for (j = 0; j < col; j++){
        free (dictionary[i][j]);
    }
    free (dictionary[i]);
}

free (dictionary);

您可以在此处看到有关如何释放二维数组的说明性示例。 希望对您有用:)

困惑来自于您不清楚任务的事实。

  • 首先,如果dictionary[i][j]必须指向一个字符串,它是一个char * ,则dictionary[i][j]必须是一个char **因为它指向一个指针。 因此, dictionary[i]必须为char ***而dictionary必须为char ****

另一方面,如果字典必须为char *** ,则每个dictionary[i][j]必须包含一个char而不是char * ,如user3112989所述,因此您的任一限制都是错误的。

因此,要回答您的问题, free(dictionary[i][j])会释放它指向的字符串,只要您在代码中的其他地方执行类似dictionary[i][j] = pointer_to_string_i_j; ,但是在那种情况下,您不必分配它们,因为它们所指向的数据已经具有一个内存块(如果您已处理过)。

  • 其次,避免强制转换malloc返回的指针(除非您的老师要求您这样做,但您应该与他讨论)。 您可以在这里找到有关在C语言中为什么不需要它以及如何可能隐藏其他问题的多个讨论。

简短的答案是:从malloc返回的每个指针最终都必须传递给free

稍长一点的答案:每次调用malloc ,它将分配一个连续的内存块,并返回一个指向该块的指针。 当该指针传递到free ,它将整个内存块返回给操作系统。 如果您用dictionary[i][j] = malloc(10000000)分配了10 MB,那么free(dictionary[i][j])将释放所有10 MB。

由于dictionary[i]本身是指向动态分配的内存块的指针,因此您还需要free(dictionary[i]) - 释放dictionary[i][j]每个字符串之后

在考虑释放之前,我们应该确保allocateArray()是正确的,但事实并非如此:

        dictionary[i] = (char**)malloc(sizeof(char*));

上面的语句仅分配一个char * ,仅分配dictionary[i][0]

        for(j=0;j<col;j++)
            dictionary[i][j] = (char*)malloc(sizeof(char*));

在这里,所有针对j> 0的 dictionary[i][j]都会写入未分配的内存。

您需要的而不是上面的三行代码是:

        dictionary[i] = malloc(sizeof (char *) * col);

此后,将为所有字符串(即char * )正确分配内存; 无需初始化。


现在我想释放最后一列(可以说),我该怎么办?

您必须为每行重新分配内存:

    --col;
    for (i=0; i<line; ++i)
        dictionary[i] = realloc(dictionary[i], sizeof (char *) * col);

请注意,如果您为最后一列中的字符指针分配了动态内存,则重新分配之前 ,您当然必须先free(dictionary[i][last])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM