在String操作后尝试释放内存时出错

时间:2014-11-08 18:33:30

标签: c memory memory-leaks

这是我第一次使用C编写了超过20行代码,这是我第一次使用内存管理代码。

我的代码工作正常而不在代码段中使用free,但是当我包含对free的调用时,我似乎无法使用malloc分配的任何char指针调用free。

代码段位于:http://pastebin.com/rY47bWyM

我在Minix 3.2.1上使用clang进行编译,当调用free(catenate)时程序崩溃并转储其核心。如果我添加行以释放其他char * like令牌,我会得到同样的错误。我究竟做错了什么?在我的程序的其他部分,我使用strtok,strcat等进行类似的字符串操作。我遇到了释放内存的相同问题,所以我认为我误解了一些关键的东西。

1 个答案:

答案 0 :(得分:0)

您只能分配free个内存。这意味着指针必须是从*alloc函数之一返回的值。

在您的代码中:

    char *catenate = (char *)malloc((MAX_BUFFER_SIZE * MAX_ENVP) + 1);
    char *token = (char *)malloc(MAX_BUFFER_SIZE + 1);
    char *copy = (char *)malloc(MAX_BUFFER_SIZE + 1);
    char *temp = (char *)malloc((MAX_BUFFER_SIZE * MAX_ENVP * 2) + 1);

在这里,您为catenate分配了meory。在那之后,你做:

    catenate = NULL;

丢失指向已分配内存的指针。这意味着你以后不能释放它;这是一个内存泄漏。

然后重新分配catenate

    if(path != -1){
         copy = strdup(sh->envp[path]);
         token = strtok(copy, "=");
         token = strtok(NULL, "=");
         if(token != NULL && token[0] == '/') catenate = token;
    }

现在,catenate仍然是NULL,或者它指向copy内的地址。 (它不指向copy本身,因为它是第二个标记,如果有的话。)

稍后,你释放它:

        free(catenate); // This line is problematic

砰! catenate不是已分配内存块的地址。如果它等于copy,它将释放copy,因为strdup也分配了内存。但事实并非如此。

问题是:不要从strtok获得免费指针。这些指针指向已分配的内存,在本例中为copy。完成后,免费catenate免费copy。 (但请记住:通过释放copy,您将catenate视为非法,因为它现在不再涉及合法记忆了。)

通过查看您的分配富矿,我发现您分配的太多了。并非所有指针都需要分配。这只是指针的一种用法:指示分配的内存块的头部。更常见的是,指针只指向现有内存,例如现有字符串中的标记。不要释放这样的内存,不要先将内存分配给这样的指针 - 你会泄漏它。