释放一个覆盖的指针

时间:2016-05-15 17:51:33

标签: c pointers free dynamic-memory-allocation

我有这个问题:

char** words = (char**)calloc(10, sizeof(char*));
for (int i = 0; i < 10; i++) {
    words[i] = (char*)calloc(100, sizeof(char));
}

我用这种方式创建一个字符串数组。比在代码中我覆盖指针(单词[i])

char* str = calloc(strlen(temp), sizeof(char));
//fill str
words[index] = str;

当我尝试释放内存时,我会收到HEAP CORRUPTION DETECTED错误。

for (int i = 0; i < 10; i++) {
    free(words[i]);
}
free(words);

有什么方法可以做到吗?

4 个答案:

答案 0 :(得分:0)

你很幸运得到了一个错误!释放未分配的内存只是未定义的行为,因此它可以在所有测试期间工作,只有在您将代码投入生产时才会中断...

规则是在释放之前不要删除malloc-ed指针。您可能有很好的理由覆盖words数组(我不知道代码中的所有内容),但在这种情况下,您可以使用两个不同的数组:

  • 一个你 malloc 并保留直到你释放它
  • 您最初从前者加载的一个,根据需要继续,不要用它来解放任何东西。

作为一种常见的替代方法,您应该在重用指针之前释放已分配的内存:

char* str = calloc(strlen(temp), sizeof(char));
//fill str
free(words[index]); // avoid the memory leak
words[index] = str; // correct because str points to another allocated buffer

答案 1 :(得分:0)

谢谢!现在我知道代码中有错误。

char* str = calloc(strlen(temp)+1, sizeof(char));

这实际上解决了HEAP CORRUPTION DETECTED错误,但我会根据您的建议修复代码。

答案 2 :(得分:0)

实际上这很容易。 你只需要这样做:

char** words = (char**)calloc(10, sizeof(char*));

将字符串复制到堆地址:

words[i]=strdup(temp);

这很简单。

strdup是来自<string.h>的函数,即:

char* strdup(char* s)
{
    char* ret=malloc(strlen(s)+1);
    strcpy(ret,s);
    return ret;
}

只需一步就可以分配然后复制,这是毫无意义的。

答案 3 :(得分:-1)

首先,通过说

 words[index] = str;

您将覆盖先前分配的指针,从而丢失实际指针(通过初始调用calloc()返回),从而导致内存泄漏。您应该使用strcpy()复制内容,而不是指针本身。

这样的东西
 strcpy(words[index], str);

应该为你做好工作。

话虽如此,

 char* str = calloc(strlen(temp) , sizeof(char));

看起来也错了。在 //fill str 部分时,您可能错过了null-terminator的空间。你可能需要

char* str = calloc(strlen(temp)+ 1, 1);  //sizeof char == 1, guaranteed in C