libgc: почему этот код просачивается?
Я пытался использовать 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 и она выглядит так, как надо. Так что ошибка только в 7.2d или в версии, упакованной в Ubuntu.
Обновление: libgc 7.2f, скомпилированный из исходного кода, также работает правильно. Так что это просто проблема версии Ubuntu и Debian.
2 ответа
Это может быть просто ошибка, но она также может стать жертвой ложного указателя. BDWGC - консервативный GC; если слово, которое "выглядит как" указатель, который указывает на память GC_malloced, память сохраняется. Если какой-либо ложный указатель указывает на один из узлов вашего списка, он будет случайно сохранен, и все узлы, на которые он указывает, также будут сохранены.
Это обсуждается с точки зрения слабой устойчивости ГХ. Подробности смотрите в следующем документе:
http://www.hpl.hp.com/techreports/2001/HPL-2001-251.pdf
Распространенной идиомой является ручное аннулирование следующей ссылки, когда узел не используется.