为什么Valgrind认为这种记忆确实会丢失"?

时间:2016-03-25 10:28:00

标签: c memory-leaks malloc valgrind

Valgrind报告说,Texture * tex肯定会丢失。但是我将这个指针保存在mtl-> tex中以便以后释放它。以下是来自valgrind的详细信息:

  

== 17191 == 1个块中的4个字节肯定会在丢失记录1中丢失1   == 17191 ==在0x4C2ABD0:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)   == 17191 == by 0x4005FA:assignTex(test.c:30)   == 17191 == by 0x400689:main(test.c:47)

这是代码(MCVE):

#include <stdlib.h>
#include <string.h>

typedef struct Tex {
    int a;
} Tex;

typedef struct MTL {
    char *textureFilename;
    struct Tex *tex;
} MTL;

void freeMtl(MTL *mtl) {
    if(!mtl) return;

    if(mtl->tex) free(mtl->tex);
    free(mtl);
}

void doStuff(Tex *tex) {
    tex->a = 5;
}

char err_is_error_set() {
    return 0;
}

void assignTex(MTL *mtl) {
    if(strlen(mtl->textureFilename) != 0) {
        Tex *tex = (Tex*)malloc(sizeof(Tex));
        memset(tex, 0, sizeof(Tex));

        doStuff(tex);
        if(err_is_error_set()) {
            return;
        }

        mtl->tex = tex;
    }
}

int main(int argc, char **argv) {
    MTL *mtl = (MTL*)malloc(sizeof(MTL));
    memset(mtl, 0, sizeof(MTL));
    mtl->textureFilename = "Test";

    assignTex(mtl);
    assignTex(mtl);

    freeMtl(mtl);

    return 0;
}

为什么它绝对丢失了?

2 个答案:

答案 0 :(得分:1)

例如,如果发生错误,则由于此代码而导致内存泄漏

    bmp_load_bitmap(bmp, mtl->textureFilename, 1/*flip vertically*/);
    if(err_is_error_set()) {
        return 0;
    }

bmp没有被释放。

此代码段中的情况也是如此

    tex_create_texture(tex);
    if(err_is_error_set()) {
        return 0;
    }

同样检查内存分配是否成功更安全。

答案 1 :(得分:0)

如果程序完成后给定指针未被释放,Valgrind会给出“绝对丢失”的消息。在我的情况下,错误是后来在代码 tex 中分配了新值并且先前的值泄露(assignTex(mtl)被调用两次)。