使用calloc和free后内存泄漏?

Mon*_*ona 0 c valgrind memory-leaks

我用"valgrind --leak-check = full"测试了我的软件,它显示:

==90862== 7,627 bytes in 4 blocks are definitely lost in loss record 858 of 897
==90862==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==90862==    by 0xD64991C: concat(int, ...) (Client.cpp:150)
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么,因为我在calloc之后使用free().这是我的代码:

char* p = concat(2, buffOld, buff);
char *x;
    while(true) {
        x = p;
        p = strstr(p,"\\final\\");
        if(p == NULL) { break; }
        *p = 0;
        p+=7;
        parseIncoming((char *)x,strlen(x));
    }
free(p);
Run Code Online (Sandbox Code Playgroud)

而"concat"功能:

char* concat(int count, ...)
{
    va_list ap;
    int i;

    // Find required length to store merged string
    int len = 1; // room for NULL
    va_start(ap, count);
    for(i=0 ; i<count ; i++)
        len += strlen(va_arg(ap, char*));
    va_end(ap);

    // Allocate memory to concat strings
    char *merged = (char*)calloc(sizeof(char),len);
    int null_pos = 0;

    // Actually concatenate strings
    va_start(ap, count);
    for(i=0 ; i<count ; i++)
    {
        char *s = va_arg(ap, char*);
        strcpy(merged+null_pos, s);
        null_pos += strlen(s);
    }
    va_end(ap);

    return merged;
}
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

max*_*x66 6

我无法理解为什么,因为我在calloc之后使用free()

是的,但是(如果我理解正确的话)你free()错了指针.

您应该复制p另一个指针(在修改它之前)和free()保存副本.

看看你的代码

char* p = concat(2, buffOld, buff);
char *x;
    while(true) {
        x = p;
        p = strstr(p,"\\final\\");
        if(p == NULL) { break; }
        *p = 0;
        p+=7;
        parseIncoming((char *)x,strlen(x));
    }
free(p);
Run Code Online (Sandbox Code Playgroud)

指针p初始化与释放calloc-ED指针但whilecicle修改它,只有当返回pNULL.

所以,当你打电话的时候

free(p)
Run Code Online (Sandbox Code Playgroud)

你在打电话

free(nullptr)
Run Code Online (Sandbox Code Playgroud)

---编辑---

我还是不明白.我在最后添加了free(x),它崩溃了

我最初的建议free(x)是我的错误,因为我没有将注意力指向xp值初始化但在while循环中被修改的事实.再次感谢Johnny Mopp指出我的注意力.

我建议使用另一个变量来记住原始值p(返回的确切值calloc())并释放该值.

就像是

char* p = concat(2, buffOld, buff);
char *x;
char * const  forFree = p; /* <--- saving calloc() returned value */

while(true) {
    x = p;
    p = strstr(p,"\\final\\");
    if(p == NULL) { break; }
    *p = 0;
    p+=7;
    parseIncoming((char *)x,strlen(x));
}

free(forFree);
Run Code Online (Sandbox Code Playgroud)