strdup() 导致内存泄漏?

strdup() causing memory leaks?

我实现了一个 returns 字符串的函数。它接受一个整数作为参数 (age),returns 一个格式化的字符串。

一切正常,除了我有一些疯狂的内存泄漏。我知道 strdup() 是造成这种情况的原因,但我试图研究一些修复方法但无济于事。

我的代码是:

const char * returnName(int age) {

    char string[30];

    sprintf( string, "You are %d years old", age);

    return strdup(string);
}

Valgrind 的输出是:

==15414== LEAK SUMMARY:
==15414==    definitely lost: 6,192 bytes in 516 blocks
==15414==    indirectly lost: 0 bytes in 0 blocks
==15414==      possibly lost: 0 bytes in 0 blocks
==15414==    still reachable: 0 bytes in 0 blocks
==15414==         suppressed: 0 bytes in 0 blocks

非常感谢解决此内存泄漏问题的任何帮助。

来自 man strdup:

Memory for the new string is obtained with malloc(3), and can be freed with free(3).

因此您需要 free space 由 strdup 分配和 return 编辑。

假设您这样调用 returnName

 const char* str = returnName(3);

完成 str 后,您可以 free 像这样:

free((char*) str);

需要强制转换,因为 free 需要一个 非常量 void*。这种显式转换在这里是可以的,因为 returnName 实际上应该 return 常量数据 1。调用 free 在这里只是一个令人讨厌的实现细节。


1 正如@M.M 在对此答案的评论中所讨论的那样。

strdup() 本质上等同于

char* dup = malloc(strlen(original) + 1);
strcpy(dup, original);

因此您需要记得在使用完字符串后调用 free()

const char* name = returnName(20);
/* do stuff with name */
free((void*)name);

如果您不调用 free(),那么 valgrind 当然会报告泄漏。

strdup 看起来像这样:

char *strdup(const char *str){
    size_t n = strlen(str) + 1;
    char *dup = malloc(n);

    if(dup){
        strcpy(dup, str);
    }

    return dup;
}

如您所见,也涉及 malloc,这意味着在您使用 strdup 动态分配该内存后的某个时刻,您必须 free不需要了。

内存泄漏的原因不是来自对 strdup() 的调用,而是因为发布函数的调用者在处理完字符串后未能将返回的指针传递给 free()。

const char * returnName(int age) {
    char string[30];
    sprintf( string, "You are %d years old", age);
    return strdup(string);
}

return returnName() 的类型是 const char*。因此,您不能将 returned 值保存到 char* 类型变量。将 returned 值保存到 const char* 变量并将其 cast 保存到 char*,同时生成内存 free

const char* retName = returnName(3);
// Use retName
free((char*)retName);