lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> The problem is that an anonymous function passed to on_click() has an
> upvalue which refers to the button, which implies that the button's __gc
> method will not be called while the function exists. But the function is
> referenced in the "refs" table and will not vanish until the destruction
> of C++ object. Hence we get a circular reference which causes a memory
> leak.

I had a similar problem when I was writing my own lua wrapper code.
The solution I ended up going with was to not have Lua hold the full
object as userdata, but rather to have it hold a pointer to the object
as userdata. That means you may have many userdata that actually point
at the same object. You then keep a reference count of how many
userdatas represent your object. You can do the reference counting by
using the object itself as a lightuserdata as the key into a table
containing the reference counts. When the __gc metamethod is called
and frees the last reference to an object, you can delete it and
free/delete/nil any data it was using.

So this code:
> Button* self = (Button*)lua_touserdata(L, 1);

becomes this:
> Button* self = *(Button**)lua_touserdata(L, 1);

And for extra clarity, you can wrap that in a template so you have a
nice function like this:

<template T>
lua_to(lua_State* L, int i) {
    return *(T**)lua_touserdata(L, i);
}

For a more robust example, have a look at this library I posted
ealier, which sounds like it does roughly what you're trying to do:

https://bitbucket.org/alexames/luawrapper