Lua:垃圾收集+ userdata

Nic*_*unt 5 c memory lua garbage-collection

假设以下情况:

typedef struct rgb_t {float r,g,b} rbg_t;

// a function for allocating the rgb struct
rgb_t* rgb(r,g,b) {
 rgb_t* c = malloc(sizeof(rgb_t));
 c->r=r;
 c->g=g;
 c->b=b;
 return c;
}

// expose rgb creation to lua
int L_rgb (lua_State* L) {
 rgb_t** ud = (rgb_t **) lua_newuserdata(L, sizeof(rgb_t *));
 *ud = rgb(lua_tonumber(L,1),lua_tonumber(L,2),lua_tonumber(L,3));
 return 1;
}
Run Code Online (Sandbox Code Playgroud)

当从Lua调用L_rgb函数时,会发生两次分配.Lua分配新的userdata并为结构分配rgb构造函数.当变量超出Lua的范围时,userdata变量会发生什么?如果是垃圾收集结构的分配会发生什么?

RBe*_*eig 12

您有两种解决此问题的方法,两种方法都适用于您的具体情况.其他情况会让你更强烈地选择一个而不是另一个.

  1. 您可以像在示例中那样执行操作,并使用malloc()获取私有数据块,并在完整的用户数据中存储指向它的指针.如果执行此操作,则必须在userdata上设置metatable,并__gc在userdata收集垃圾时使用其metamethod释放已分配的块.

  2. 您可以使用userdata本身作为私有数据块的分配,通过调用lua_newuserdata()代替malloc().在这种情况下,您不需要使用__gc元方法,因为Lua将直接管理分配的生命周期.你可能还是希望有一个元表,这样就可以使用其__index进入创建名为成员的外观r,g以及b从你的结构检索它们的值.

无论哪种方式,您都需要考虑错误处理.

  • 方法#2将减轻您的跟踪分配 - 在Lua错误和堆栈倒带时,Lua的GC仍将根据需要跟踪和释放代码块. (2认同)