2010-12-04 70 views
1

我試圖找到一些明確解釋的教程,在釋放內存時需要記住的事情是什麼。但是我找不到這樣的東西。任何人都可以讓我知道程序員在處理C中的內存時應該記住什麼是主要的東西。我目前正在處理鏈接列表。有些情況下,新鏈接列表創建使用2個或多個現有鏈接list.For例如:在C中釋放內存時應該考慮的主要事情是什麼?

list l1; 
list l2 
list l3 = list_append(l1,l2) 
list l4 = list_append(l3,l1) 
list l5 = list_append(l3,l4) 

什麼是釋放,我要跟着解除分配內存的序列?

此處list_append是返回列表副本的函數。

+2

不知道'list_append'是幹什麼的。它是複製輸入列表,還是將它們鏈接在一起? – 2010-12-04 17:29:17

+0

@Steve the list append copy the input lists。 – thetna 2010-12-04 17:32:53

回答

3

當使用malloc/free函數族時,有兩條規則需要遵守。

  1. 您可以通過一個malloc家庭分配器僅free有效的記憶回來了,釋放它使之無效(所以雙釋放是一個錯誤的釋放不通過malloc獲得的內存)。
  2. 在釋放內存後訪問內存是錯誤的。

這裏是重要的部分:分配器提供沒有設施,以幫助您遵守這些規則

你必須自己管理它。這意味着您必須安排程序的邏輯以確保始終遵守這些規則。這是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 

鑑於你有節點列表,添加和刪除,你可能考慮結構所有權模式,所以請記住:一旦你給予該結構的結構,你只需就可以通過該結構來訪問它。

1

第一個原則是:

不管你分配(用calloc/ malloc的),你需要釋放,最終。如果名單深在每個複製

在你追加的情況下,我看不出有什麼問題。你需要分開釋放每個列表。

2

一般的問題意義不大,唯一合理的答案似乎很明顯:

  1. 那記憶被一審動態分配
  2. ,繼釋放您不要嘗試使用內存再次
  3. 你至少要維護一個指向分配的指針,直到你需要釋放它(即不要讓你對該塊的唯一引用超出範圍或被銷燬)。

第二個要求可以通過在釋放後將指針設置爲NULL或零來輔助,但指針可能在其他地方被保持,但它不是簡單的。

第三個要求尤其是複雜數據結構中的問題,其中分配的內存可能包含本身包含指向已分配內存的指針的結構。在取消分配更高級別的結構之前,您當然需要釋放這些資源。

2

任何人都可以讓我知道什麼是 主要事情是一個程序員 應該記住,而deallocting C中的內存

的基本原則是非常簡單的:任何內存使用分配包括malloc,callocrealloc的* alloc函數系列必須通過相應的free()調用重新分配。

當傳遞指針(內存地址)free(),記住的只有有效存儲器地址可以傳遞給free()是以前由的* ALLOC函數返回一個內存地址。一旦內存地址傳遞給free(),該內存地址不再有效,不能用於任何其他目的。

0

使用valgrind(1)向您展示在您的特定情況下終止時仍存在哪些對象,然後修改您的代碼以確保釋放不必要的對象。

0

那麼最好的答案是一個問題..爲什麼你是用C編寫代碼,而不是使用更高級別的語言和更好的內存管理?

相關問題