2015-07-13 148 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