用新的字符串替换堆上的字符串

时间:2015-07-23 16:18:54

标签: c memory-leaks malloc dynamic-memory-allocation

我觉得使用动态类型语言已经激发了我对此的直觉!

假设我malloc为一个字符串空间,然后用另一个malloc(使用第一个数据)更新该指针,那是内存泄漏吗?

char* my_string = (char*)malloc(length + 1);
(void)snprintf(my_string, length, "blah...");

my_string = some_manipulation(my_string);

我们有char* some_manipulation(const char* str);为其输出分配内存,该内存是从提供的参数生成的(可能长度不一样)。

第一个malloc现在已经丢失,但占用空间,直到退出?

3 个答案:

答案 0 :(得分:2)

如果你在同一个指针上有两个malloc次调用和一个free,那么几乎肯定会有泄漏(第一个malloc失败)。

每个成功的malloc都应该在指针生命周期的某个地方有一个关联的free

泄漏:

foo* bar = NULL;
bar = malloc(sizeof(foo) * 10);
if (bar) {
    bar = malloc(sizeof(foo) * 20);
}
else {
    fprintf(stderr, "Error: Could not allocate memory to bar\n");
    exit(EXIT_FAILURE);
}
free(bar);
bar = NULL;

没有泄漏:

foo* bar = NULL;
bar = malloc(sizeof(foo) * 10);
if (bar) {
    free(bar);
    bar = NULL;
}
else {
    fprintf(stderr, "Error: Could not allocate memory to bar\n");
    exit(EXIT_FAILURE);
}
bar = malloc(sizeof(foo) * 20);
if (bar) {
    free(bar);
    bar = NULL;
}
else {
    fprintf(stderr, "Error: Could not allocate memory to bar\n");
    exit(EXIT_FAILURE);
}

答案 1 :(得分:2)

  

假设我malloc为一个字符串空间,然后用另一个malloc(使用第一个数据)更新该指针,那是内存泄漏吗?

是的,如果你没有存储string的第一个值,那么在第二次调用malloc()之前覆盖它。

泄露代码

char * p = malloc(42);   
p = malloc(41);

/* here the program leaks 42 bytes. */

您只能free()第二次通话的41个字节

free(p);

因为对42字节块的引用丢失。

非泄露代码

char * p = malloc(42);
char * q = p;
p = malloc(41);

在这里你没有泄密,你仍然可以这样做:

free(p); /* Frees 41 bytes. */
free(q); /* Frees 42 bytes */
  

使用第一个

中的数据

所有这些根本不依赖于已存储的内容(或不是)分配的内存。

答案 2 :(得分:2)

是的,当然。你似乎把你的字符串想象成一个不可变对象,这是一个很好的概念,但是没有利用你释放占用的内存。

如果您知道对函数的调用在概念上使输入字符串无效(因此,调用函数后调用者不再需要它),您可以改为执行以下操作:

int some_manipulation(char **str)
{
    char *ret = malloc(...);
    /* handle error, return -1 */
    /* do whatever manipulation */
    free(*str);
    *str = ret;
    return 0;
}