1

另一个C问题:

假设我有一个具有类型指针成员的结构char*

当我想初始化我调用的结构实例时malloc

MyStruct* ptr = (MyStruct*)malloc(sizeof(MyStruct)

然后为成员分配 256 字节的内存char*

ptr->mem = (char*)malloc(sizeof(char)*256);

当我调用时,指针成员和它指向的内存会发生什么 free(ptr);?当我用 valgrind 检查程序时,我发现我有内存泄漏,但是当我明确调用时,free(ptr->member);我仍然有内存泄漏,并且 valgrind 显示“无效的免费”错误

管理成员指向的内存的正确方法是什么?

4

3 回答 3

3

您必须先释放 ptr->member,然后再释放 struct

free(ptr->member);
free(ptr);
于 2012-04-09T21:08:36.927 回答
3

只要您调用free(ptr),其中的任何成员ptr都不再有效。你不能对他们做任何事。但是指向的内存ptr->mem仍然需要释放。因此,您必须free(ptr->mem)首先,或者以其他方式将该指针复制到某处,以便有一个有效的指向空闲的指针。

分配和释放复合结构的一般模式类似于(将它们包装在执行此操作的干净函数中很有帮助):

MyStruct* MakeMyStruct() {
    MyStruct* ptr = malloc(sizeof(MyStruct)); //N.B. don't need cast if it's C
    ptr->mem = malloc(sizeof(char)*256);
    //initialise other members
    return ptr;
}

void DestroyMyStruct(MyStruct *ptr) {
    //Free members first, then the struct
    free(ptr->mem);
    free(ptr);
}

如果某些成员本身是复杂的结构,则它们将依次被分配/释放,MakeWhateverDestroyWhatever不是在上述两个函数中使用mallocand 。free

于 2012-04-09T21:16:01.293 回答
2

经验法则是free每次(成功)调用都需要一个malloc(通常,这些调用以相反的顺序发生)。

如果你只有free(ptr),那么你有内存泄漏(因为没有办法访问分配给 的内存ptr->mem)。如果你只是free(ptr->mem),那么你还没有完全清除(不如内存泄漏那么糟糕)。

于 2012-04-09T21:08:24.793 回答