我是C的新手,所以这可能很明显,但我还是不确定。 Java为我照顾了这个^^
我有一个替换表,输入字符串和一个函数str_replace,它对字符串做了一些工作。 str_replace
在内部调用malloc为新字符串获取空间(它返回一个新分配的char *。
char* color_tags(char* s) {
char* out = s;
// in real, the table is much longer
static char* table[4][2] = {
{"<b>", BOLD},
{"<u>", UNDERLINE},
{"</b>", BOLD_R},
{"</u>", UNDERLINE_R},
};
for(int r=0; r<4; r++) {
// here's what bothers me
out = str_replace(table[r][0], table[r][1], out);
}
return out;
}
正如您所看到的,char* out
被指向新字符串的指针取代,因此旧字符串显然最终会导致内存泄漏 - 如果我不完全理解它。
对此更好的方法是什么?
答案 0 :(得分:1)
[这更多的是评论而不是答案 - abacabadabacaba已经发布了答案 - 但我希望它会澄清一些事情。]
我认为内存泄漏在此声明中:
str_replace
内部调用malloc以获取新字符串的空间[...]
[强调我的]内存管理是C中的一个基本问题,如果一个函数分配它本身没有解除分配的内存,那么这是该函数的一个主要属性,并且需要记录一个-front,以及有关调用者应该如何处理的信息。它不应被视为函数的“内部”,并且您不应该读取函数的源代码的全部内容以确定它。这足以让我对函数的其余部分产生怀疑(实际上,快速浏览一下该函数就足以发现很多问题:它的参数类型应该是const char *
而不是char *
;它应检查malloc
的返回值;通过使用new_subject
跟踪strcat
的尾部或更清晰,可以提高效率,而不是当前最差的 - 双世界;等等。)。
您最初没有编写str_replace
,但您可以修改自己的版本,因此您应该更改其文档:
使用字符串
中的另一个字符串搜索并替换字符串
这样的事情:
创建并返回
subject
的副本,但所有出现的子字符串search
都替换为replace
。返回的字符串是使用malloc
新分配的;调用者应使用free
。
(您的color_tags
函数需要类似的文档,因为它也会使用malloc
返回一个新分配的字符串。)
手头的文档中,有一个明确的“所有权”链:str_replace
的调用者获取它返回的字符串的所有权。因此color_tags
必须为free
,返回的每个字符串调用str_replace
,除了 color_tags
本身将返回的字符串(反过来将是由color_tags
的来电者“拥有”。因此,abacabadabacaba的回答。
答案 1 :(得分:0)
代码总共泄漏了3个字符串:除了最后一个之外的每个迭代后一个。解决方案是在使用后释放每个字符串。代码可能如下所示:
for(int r=0; r<4; r++) {
char* new_out = str_replace(table[r][0], table[r][1], out);
if (r>0) {
// out is an intermediate value which will never be used again, free it
free(out);
}
out = new_out;
}