libgc:为什么这段代码泄漏了?

时间:2015-07-13 10:14:18

标签: c garbage-collection boehm-gc

我试图在这个简单的代码中使用libgc(BDW垃圾收集器)。

注意,该引用仅限于假“列表”中的最后一个节点,因此,生存集只是最后两个节点。

// 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 = 100000000 ./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编译了trunk版本,它看起来运行正常。所以,bug只出现在7.2d或打包到Ubuntu的版本中。

更新:从源代码编译的libgc 7.2f也能正常工作。所以这只是Ubuntu和Debian的版本问题。

2 个答案:

答案 0 :(得分:3)

它可能只是一个错误,但它也可能是一个错误指针的受害者。 BDWGC是一个保守的GC;如果一个单词“看起来像”指向碰巧指向GC_malloced内存的指针,则保留内存。如果某个错误指针恰好指向您的列表节点之一,它将被意外保留,并且所有指向它的节点也会被保留。

根据弱GC稳健性进行讨论。有关详细信息,请参阅以下文章:

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

常见的习惯用法是在节点未使用时手动使下一个链接无效。

答案 1 :(得分:0)

因为你在无限循环中分配内存。