无法释放动态分配的二维数组

时间:2015-04-24 13:13:29

标签: c arrays memory memory-management

请考虑以下代码:

#include <stdio.h>

char** baz_alloc(int size)
{
    char ** b = malloc((size+1) * sizeof(char*));
    for (int i = 0; i < size; i++)
        b[i] = "baz";
    b[size] = NULL;

    return b;
}

void baz_print(char** baz)
{
    char** b = baz;
    while (*b != NULL)
    {
        printf("%s\n", *b);
        b++;
    }
}

void baz_free(char** baz)
{       
    int len = 0;
    char** b = baz;
    for (; *b != NULL; len++, b++);

    for (int i = 0; i < len; i++)
        free(baz[i]);
    free(baz);
}

int main()
{
    char** baz = baz_alloc(10);
    baz_print(baz);
    baz_free(baz);

    getch();
    return 0;
}

程序在调用free函数时崩溃。我在这里看了类似的例子,它看起来几乎一样。我的代码出了什么问题?

感谢。

3 个答案:

答案 0 :(得分:5)

您在此指针上调用free()

b[i] = "baz"

该指针未分配malloc()(或calloc()realloc()等)。

答案 1 :(得分:3)

你不能释放字符串

free(baz[i]);

试图摆脱

b[i] = "baz";

作为一项规则:只允许您分配的内容,分配位置(在导致分配的最顶层函数中),反向分配顺序。

例如:

int main()
{
  char** baz = baz_alloc(10); //'creating' baz
  baz_print(baz); //using baz
  baz_free(baz); //freeing baz
  [...]
}

是非常好的练习。

您的baz_free功能只需使用1 free,因为malloc只调用了1 baz_alloc

//Allocation
char ** b = malloc((size+1) * sizeof(char*));

//Freeing
free(b); // or in your function free(baz);

如果您的baz_alloc函数有b[i] = malloc(...),那么您的baz_free代码几乎是正确的(您不需要迭代两次,就可以调用free(b)在你的第一个循环中。)

答案 2 :(得分:1)

这个循环:

for (int i = 0; i < len; i++)
    free(baz[i]);

不应该存在,因为从未分配过内存。

但是以下一行:

free(baz);

需要存在,因为通过调用malloc()创建了指向char的初始指针数组。