Проблема связана с владением.Давайте возьмем ваши сценарии Lua:
a = structaInit();
b = structbInit();
Это создает объекты C, которые Lua теперь владеет .Lua решит, когда освободить память для этих объектов.
Так что же с этим?
structbSetA( b, a ); -- This add ++a.reference
Прежде всего, structbSetA
должен быть членом b
черезметатабельный (так становится b:setA(a)
).Но что более важно, кому принадлежит a
?
Луа.Потому что он должен владеть А;Lua не может полностью отказаться от владения объектом, который все еще находится в памяти Lua.Это означает, что ваш внутренний счетчик ссылок в конечном итоге не имеет смысла;единственное, что имеет значение, это Lua.
Если вы намереваетесь сохранить значение a
в b
, так что b
может ссылаться на a
, пока b
еще жив,тогда вам нужно создать эти отношения с помощью Lua методов.Вы не можете просто прикрепить указатель C к a
в b
и ожидать, что все будет хорошо.
Самый простой способ сделать это - создать для каждого объекта, который вы создаете, таблицу вРеестр Lua, в котором хранится объект Lua для любых ссылок.Когда объект уничтожен, вы заходите в реестр Lua и удаляете из него эту таблицу, что приводит к уничтожению любых ссылочных объектов Lua.Очевидно, вам нужно будет изменить это значение, когда оно будет изменено последующими вызовами на structbSetA
.
Кроме того, почему вы выставляете это Lua:
a.reference = 0;
Этоужасный API.Код Lua никогда не должен иметь дело со счетчиком ссылок.Вы также никогда не должны предоставлять явный «бесплатный» метод Lua, если только вам не нужно, чтобы Lua высвободил какой-либо ресурс сразу после его использования.И это only должно быть необходимо для ресурсов типа OS, таких как дескрипторы FILE и тому подобное.Для обычного объекта позвольте сборщику мусора выполнить свою работу.
Не открывайте C-isms для кода Lua.Пусть код Lua будет выглядеть как код Lua.