Я работал над некоторыми функциями пользовательского языка программирования, написанного на c.В настоящее время я работаю над системой, которая выполняет подсчет ссылок для объектов на языке, которые в c представлены как структуры, среди прочего, со счетчиком ссылок.
Также есть функция, которая может освободить все выделенные в данный момент объекты (скажем перед выходом программы очистить всю память).Теперь в этом и заключается проблема.
Я думал о том, как сделать это лучше, но у меня возникают некоторые проблемы.Позвольте мне набросать ситуацию немного:
2 новых целых числа выделены.оба имеют счетчик ссылок 1
1 новый список назначен, также с счетчиком ссылок 1
теперь оба целых идут в списке, что дает им счетчик ссылок 2
после этих действийоба целых числа почему-то выходят из области видимости, поэтому их счетчик ссылок падает до 1, поскольку они все еще находятся в списке.
Теперь я закончил с этими объектами, поэтому я запустил функцию, чтобы удалить все отслеживаемые объекты.Однако, как вы могли заметить, список и объекты в списке имеют одинаковый счетчик ссылок (1).Это означает, что нет способа решить, какой объект освободить первым.
Если бы я освободил целые числа перед списком, список попытается уменьшить счетчик ссылок на целые числа, которые были освобождены ранее, что приведет к segfault.
Если список будет освобожден раньшецелые числа, это уменьшило бы число ссылок целых чисел до 0, что также автоматически освобождает их, и не нужно предпринимать никаких дальнейших шагов для освобождения целых чисел.Они больше не отслеживаются.
В настоящее время у меня есть система, которая работает большую часть времени, но не для примера, который я привел выше, где я освобождаю объекты на основе их счетчика ссылок.Самое высокое количество последних.Это, очевидно, работает только до тех пор, пока целые числа имеют большее число ссылок, чем список, что видно из приведенного выше примера, не всегда так.(Это работает только при условии, что целые числа не выпали из области видимости, поэтому у них все еще более высокое число ссылок, чем в списке)
Примечание: я уже нашел один способ, который мне действительно не нравится: добавлениефлаг для каждого объекта, указывающий, что он находится в контейнере, поэтому не может быть освобожден.Мне не нравится это, потому что это добавляет некоторые накладные расходы памяти для каждого выделенного объекта, и когда есть циклическая зависимость, ни один объект не будет освобожден.Конечно, детектор циклов мог бы это исправить, но желательно, чтобы я делал это только с подсчетом ссылок.
Позвольте мне привести конкретный пример описанных выше шагов:
//this initializes and sets a garbage collector object.
//Basically it's a datastructure which records every allocated object,
//and is able to free them all or in the future
//run some cycle detection on all objects.
//It has to be set before allocating objects
garbagecollector *gc = init_garbagecollector();
set_garbagecollector(gc);
//initialize a tracked object fromthe c integer value 10
myobject * a = myinteger_from_cint(10);
myobject * b = myinteger_from_cint(10);
myobject * somelist = mylist_init();
mylist_append(somelist,a);
mylist_append(somelist,b);
// Simulate the going out of scope of the integers.
// There are no functions yet so i can't actually do it but this
// is a situation which can happen and has happened a couple of times
DECREF(a);
DECREF(b);
//now the program is done. all objects have a refcount of 1
//delete the garbagecollector and with that all tracked objects
//there is no way to prevent the integers being freed before the list
delete_garbagecollector(gc);
что, конечно, должно произойти, это то, что в 100% случаев список освобождается раньше, чем целые числа.
Что может быть более разумным способом освобождения всех существующих объектов таким образом, чтобы объекты, хранящиеся в контейнерах, неосвобожден до того, как контейнеры будут в них?