當使用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