1

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

一切都运行良好,除了我有一些疯狂的内存泄漏。我知道 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

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

4

5 回答 5

5

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 当然会报告泄漏。

于 2015-10-19T22:10:48.393 回答
3

来自man strdup

新字符串的内存使用 获得 malloc(3),并且可以使用 释放free(3)

所以你需要free分配和返回的空间strdup

假设您这样调用returnName

 const char* str = returnName(3);

完成后你str可以free这样:

free((char*) str);

演员表是必需的,因为free需要一个非常量 void*。这种显式转换在这里没问题,因为returnName实际上应该返回常量数据1。调用free在这里只是一个讨厌的实现细节。


1正如在对此答案的评论中与@MM 讨论的那样。

于 2015-10-19T22:09:10.517 回答
3

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在不再需要它之后再分配它。

于 2015-10-19T22:11:43.650 回答
1

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

于 2015-10-19T23:09:39.873 回答
1
const char * returnName(int age) {
    char string[30];
    sprintf( string, "You are %d years old", age);
    return strdup(string);
}

返回类型returnName()const char*. 因此,您不能将返回值保存到char*类型变量中。将返回值保存到const char*变量中,并castchar*制作内存时保存free

const char* retName = returnName(3);
// Use retName
free((char*)retName);
于 2017-07-22T05:57:44.247 回答