2015-07-13 3 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; 
    } 
} 

Но он не мог оставаться в пределах памяти:

$ НКУ -O0 gc.c -lgc -o дс

$ 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

Обновление: я только что скомпилировал версию trunk от https://github.com/ivmai/bdwgc и он выглядит правильно. Так что ошибка только в 7.2d или в версии, упакованной в Ubuntu.

Обновление: libgc 7.2f, скомпилированный из источника, также работает правильно. Так что это только проблема версии Ubuntu и Debian.

+0

@leppie, 'last' делает доступным только последний выделенный элемент, и ничто не может быть доступно из последнего выделенного элемента. – chill

+0

@chill: Мой плохой тогда, p – leppie

+0

размер кучи GC установлен в 100 миллионов. вероятно, больше, чем доступная память. Примечание. Введенный код не может передать выделенную память GC_free(). цикл «навсегда» для цикла сохраняет выделение памяти до тех пор, пока память не будет исчерпана. И.Е. логика программы должна быть изменена, чтобы не выделять все больше и больше памяти. эта строка: 'last = nuo;' нормально, когда последний == NULL, после этого он повреждает связанный список – 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

Смежные вопросы