当使用malloc
/free
函数族时,有两条规则需要遵守。
- 您可以通过一个
malloc
家庭分配器仅free
有效的记忆回来了,释放它使之无效(所以双释放是一个错误的释放不通过malloc获得的内存)。
- 在释放内存后访问内存是错误的。
这里是重要的部分:分配器提供没有设施,以帮助您遵守这些规则。
你必须自己管理它。这意味着您必须安排程序的逻辑以确保始终遵守这些规则。这是c并且巨大的乏味和复杂的责任倾倒在你的肩膀上。
让我提出两个模式是比较安全的:
分配和释放在同样的情况下
//...
{
SomeData *p = malloc(sizeof SomeData);
if (!p) { /* handle failure to allocate */ }
// Initialize p
// use p various ways
// free any blocks allocated and assigned to members of p
free p;
}
//...
在这里,你知道数据p指向被分配一次,并释放一次,并且只使用在之间。如果SomeData的内容的初始化和释放是不平凡的,你应该包起来的一对夫妇的功能,使得这降低了
//...
{
SomeData *p = NewSomeData(i,f,"name"/*,...*/); // this handles initialization
if (!p) { /* handle failure to allocate */ }
// use p various ways
ReleaseSomeData(p) // this handles freeing any blocks
// allocated and assigned to members of p
}
//...
称它是“范围所有权”。您会注意到它与本地自动变量没有多大区别,并且只提供了几个选项,这些选项对于自动变量而言不可用。
呼叫第二个选项“结构所有权”:删除分配的内存块这里的责任是交给一个更大的结构:
List L = NewList();
//...
while (something) {
// ...
Node n= NewNode(nodename);
if (!n) { /* handle failure to allocate */ }
ListAdd(L,n); // <=== Here the list takes ownership of the
// node and you should only access the node
// through the list.
n = NULL; // This is not a memory leak because L knows where the new block is, and
// deleting the knowledge outside of L prevents you from breaking the
// "access only through the structure" constraint.
//...
}
// Later
RemoveListNode(L,key); // <== This routine manages the deletion of one node
// found using key. This is why keeping a separate copy
// of n to access the node would have been bad (because
// your separate copy won't get notified that the block
// no longer valid).
// much later
ReleaseList(L); // <== Takes care of deleting all remaining nodes
鉴于你有节点列表,添加和删除,你可能考虑结构所有权模式,所以请记住:一旦你给予该结构的结构,你只需就可以通过该结构来访问它。
不知道'list_append'是干什么的。它是复制输入列表,还是将它们链接在一起? – 2010-12-04 17:29:17
@Steve the list append copy the input lists。 – thetna 2010-12-04 17:32:53