2015-10-19 165 views
-1

我已经实现了一个返回字符串的函数。它将一个整数作为参数(age),并返回一个格式化的字符串。strdup()导致内存泄漏?

所有的工作都很好,除了我有一些疯狂的内存泄漏事实。我知道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 

解决此内存泄漏问题的任何帮助是极大的赞赏。

+1

你已经证明,分配,那是哪里释放的代码的代码存储? –

+0

提供[mcve]。 – Olaf

+1

您是否阅读过有关'strdup'的任何文档? – juanchopanza

回答

2

首先,RTFM。 :-)

man strdup从:与 malloc(3)获得

内存为新的字符串,并且可以与free(3)被释放。

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

说你调用returnName这样的:

const char* str = returnName(3); 

后你与str做,你可以free这样的:

free((char*) str); 

需要演员因为free需要一个非constvoid*。这个明确的转换在这里没问题,因为returnName实际上应该返回不变的数据。在这里调用free只是一个令人讨厌的实现细节。


与@ M.M在评论这个答案的讨论。

+0

如果我在主要方法中进行打印,如:printf(“%s”,returnName(3));'因此在调用方法时没有变量名称,例如'str'被分配 - 如何释放它? – user3186023

+0

'const char * str = returnName(3); printf(“%s \ n”,str);' – Downvoter

+0

希望我可以避免显式声明一个新的变量,但我想这将不得不做。谢谢。 – user3186023

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

+0

下面又问了另一位用户:如果我在主要方法中打印,如下:'printf(“%s”,returnName(3));'所以当调用时没有变量名,例如'name'该方法 - 我将如何释放它?谢谢。 – user3186023

+0

@ user2832891然后,您导致了内存泄漏。您需要将变量与它关联起来,以便稍后“释放”它。 –

+0

@PCLuddite你刚刚制作了我的答案副本吗? – Michi

4

的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之后你不再需要它了。

1

内存泄漏的原因并非来自对strdup()的调用,而是因为在使用字符串完成时,已发布函数的调用方未能将返回的指针传递给free()。

0
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);