关于C#:strdup()导致内存泄漏?

strdup() causing memory leaks?

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

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

我的代码是:

1
2
3
4
5
6
7
8
const char * returnName(int age) {

    char string[30];

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

    return strdup(string);
}

Valgrind \\的输出是:

1
2
3
4
5
6
==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

对于解决此内存泄漏问题的任何帮助,我们深表感谢。


strdup()本质上等同于

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

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

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

如果您不拨打free(),则valgrind当然会报告泄漏。


strdup看起来像这样:

1
2
3
4
5
6
7
8
9
10
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对其进行存储。<铅>


来自man strdup

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

因此您需要freestrdup分配和返回的空间。

假设您像这样调用returnName

1
 const char* str = returnName(3);

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

1
free((char*) str);

需要强制类型转换,因为free需要一个非常量void*。这种显式转换在这里还可以,因为returnName实际上应该返回常量data1。在这里调用free只是一个讨厌的实现细节。

1如对此答案的注释中与@ M.M讨论的那样。


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

返回类型是const char*。因此,您不能将返回的值保留为char*类型的变量。将返回的值保存到const char*变量中,并将其保存到char*中,同时将内存free

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

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