2012-12-09 40 views
0

假設我有作爲從雙向鏈表中刪除時,如何避免內存泄漏?

class list 
{ 
    /*...*/ 

private: 
    struct node 
    { 
     node* prev; 
     node* next; 
     int* value; 
    } 

    node* first; //NULL if none 
    node* last; //NULL if none 

    /*...*/ 
} 

如果我想編寫一個函數,刪除第一個節點,並返回一個指向它的價值,這將實現泄漏內存雙鏈表這樣?

int* returnFrontValue() 
{ 
    if(list_is_Empty()) 
     throw -1; 
    else 
    { 
     node* v = first; 
     int* returnMe = v->value; 

     first = first->next; 
     if(!first) 
      last = NULL; 

     delete v; 
     first->prev = NULL; 

     return returnMe; 
    } 
} 

我很好奇,如果這個實現泄漏內存,因爲returnMe指向動態分配一個int。最好有一個int returnMe = *(v->value);,並在最後返回&returnMe;

難道我我delete v;前明確要delete v->value;?當我有很多指針時,我很困惑如何刪除內存。

+1

返回一個局部變量的地址?絕對不是更好。 – chris

+1

爲什麼每個節點都有一個指向動態分配的「int」的指針,而不是簡單的「int」成員? – interjay

+0

@interjay如果是會員,'delete v'會將其銷燬 – TeaOverflow

回答

2

我們看不到int是如何分配的,但我會對此表示它是動態分配的(作爲從您刪除的節點的單獨分配)。

在這種情況下,不,你沒有泄漏任何東西,但你很誘人的命運。這不是泄漏,因爲指向int的指針仍然存在,所以它仍然可以被刪除。但現在責任在於來電者。如果我撥打returnFrontCaller,我會得到一個值爲的指針,然後當我完成時,我需要撥打delete

這不是很直觀。一般來說new/delete調用應該在相同的地方匹配。如果我撥打new,我也打電話delete。如果new呼叫發生在其他地方,我不希望致電delete是我的責任。

但爲什麼值動態地在所有Why do you store an INT * instead of an int`分配呢?爲什麼函數返回一個指向int的指針,而不是它的副本?

如果您進行了更改,則不需要進行內存管理。調用者將得到一個int,並且不必擔心「誰撥打delete」。

或者,您可以使用智能指針類來包裝它,並處理內存管理。

+0

那麼在這個例子中,當我刪除一個節點時究竟發生了什麼?它包含三個指針,我必須單獨刪除它們嗎? –

+0

當你刪除一個節點時,如前所述,指向int *的指針將被掛起。如果主叫方丟失並且未刪除,則會發生泄漏。其他指針指向現有節點,這些節點不會被刪除操作刪除,所以它們不需要(並且不應該被刪除)刪除。 –

+0

當你刪除一個節點時,首先調用類的析構函數,然後節點類的每個成員都調用它的析構函數。對於原始指針,這不起作用(特別是,它不會**刪除指針指向的任何東西)。 – jalf