2012-04-09 55 views
1

另一种C问题: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显示“无效免费”的错误

什么是正确的方式管理内存由会员指出?

+1

您不应该在C中使用'malloc'来返回值。 – 2012-04-09 21:07:48

+0

'memcpy'有什么问题? – 2012-04-09 21:08:53

+0

@Oli Charlesworth:为什么不呢? – 2012-04-09 21:10:07

回答

2

经验法则是,您需要一个freemalloc)的每个(成功)调用(并且通常这些以相反的顺序发生)。

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

3

你必须首先释放ptr->成员,则结构

free(ptr->member); 
free(ptr); 
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而不是mallocfree

+0

+1,用于干净的功能。有人可能会争辩说,将'ptr-> mem = NULL;'添加到'DestroyMyStruct'将有助于在别处找到错误。 – 2012-04-09 21:19:20

+0

+1。抽象是你的朋友。 – 2012-04-09 22:58:37

+0

这就是我所实现的,但出于某种原因,我得到了一个double free错误。valgrind输出显示double free是来自销毁该struct的方法.. – Bob 2012-04-10 11:54:47