内存泄漏字符串?

时间:2014-03-22 18:20:22

标签: c memory malloc memory-leaks

我是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被指向新字符串的指针取代,因此旧字符串显然最终会导致内存泄漏 - 如果我不完全理解它。

对此更好的方法是什么?

2 个答案:

答案 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;
}