2015-07-13 202 views
3

我試過在這個簡單的代碼中使用libgc(BDW垃圾回收器)。libgc:爲什麼這個代碼泄漏?

請注意,該參考僅保留在假「列表」中的最後一個節點,因此,活動集僅爲最後兩個節點。

// thanks to @chill for this example 
#include <gc.h> 

struct list { 
    struct list* next; 
}; 

int main() { 
    GC_INIT(); 
    struct list *last = NULL; 
    for (;;) { 
     struct list* nuo = GC_MALLOC(sizeof(struct list)); 
     nuo->next = NULL; 
     // if next line is commented, then no leakage 
     if (last) last->next = nuo; 
     last = nuo; 
    } 
} 

但它不能存儲限度內住宿:

$ gcc的-O0 gc.c -lgc -o GC

$ GC_MAXIMUM_HEAP_SIZE =億./gc

GC Warning: Out of Memory! Trying to continue ... 
GC Warning: Out of Memory! Trying to continue ... 
GC Warning: Out of Memory! Trying to continue ... 
GC Warning: Out of Memory! Trying to continue ... 
GC Warning: Out of Memory! Heap size: 95 MiB. Returning NULL! 
Segmentation fault 

我做錯了什麼? Ubuntu 15.04 x86_64 gcc 4.9.2 libgc 7.2d-6.4

更新:我剛從https://github.com/ivmai/bdwgc編譯中繼版本,它看起來工作正常。所以,bug只在7.2d或者打包到Ubuntu的版本中。

Update:libgc 7.2f compilled from source also works properly。所以這只是Ubuntu和Debian的版本問題。

+0

@leppie,'last'只讓最後一個分配的元素可到達,並且沒有任何東西可以從最後分配的元素到達。 – chill

+0

@chill:我的不好; p – leppie

+0

GC堆大小設置爲1億。可能比可用內存更多。注意:發佈的代碼無法將分配的內存傳遞給GC_free()。 '永遠'''循環不斷分配內存,直到內存耗盡。 I.E.程序邏輯需要被修改,以避免分配越來越多的內存。這一行:'last = nuo'是ok,當last == NULL時,在調用GC_MALLOC()後,它破壞鏈表 – user3629249

回答

0

因爲您正在無限循環中分配內存。

3

它可能只是一個錯誤,但也可能是虛假指針的犧牲品。 BDWGC是一種保守的GC;如果一個單詞「看起來像」指向一個GC_malloced內存的指針,則內存被保留。如果某個錯誤指針碰巧指向您的列表節點之一,它將被意外保留,並且所有指向它的節點也將被保留。

它在弱GC健壯性方面進行了討論。請參閱下面的紙張的詳細信息:

http://www.hpl.hp.com/techreports/2001/HPL-2001-251.pdf

一個常見的成語是手動抵消下一個環節時,節點獲得使用。

+0

True。它的標題是「令人尷尬的失敗情景」。在這裏也可以找到:http://www.hboehm.info/gc/bounds.html – Ringding