2013-04-10 104 views
0

我在使用Lua的C API编写应用程序,我试图确定使用它的方式是否会留下一些悬挂指针(指向指针)。C(++)和Lua清理内存

说我有树状结构(类实际上)在C++

​​

- 假设tree已经创建并包含数据,我在Lua使用它像这样:

local root = tree:getRoot() 
root:DoSomeLeafStuff() 

现在我的C的执行getRoot() Lua看起来像这样:

int LuaStuff::TreeGetRoot(lua_State* L) 
{ 
    Tree* tree = *(Tree**)luaL_checkudata(L, 1, "MyStuff.Tree"); 

    if (tree != NULL && tree->getRoot() != NULL) 
    { 
    int size = sizeof(Leaf**); 
    *((Leaf**)lua_newuserdata(L, size)) = tree->getRoot(); // allocate a pointer to a pointer 
    lua_setmetatable(L, "MyStuff.Leaf"); 
    } 
    else 
    { 
    lua_pushnil(L); 
    } 

    return 1; 
} 

经过一些故障排除后,我能够在您期望的时候让我的Tree和Leaf对象释放。但到目前为止,我还没有找到一种令人信服的方式(至少对我来说)指针指针正在清理。

我的问题是:我可以安全地假设由Lua的lua_newuserdata()分配的内存由Lua的垃圾回收自动清理?

+0

http://lua-users.org/wiki/GarbageCollectionTutorial – hjpotter92 2013-04-10 11:41:10

回答

1

我正在做类似的事情在Lua中包装自己的对象。这就是我如何做到这一点:

/*part of the functon, buffer_s is a structure holding pointer 
to the real object and some other fields (like who actually created the object) 
*/ 
buffer_s* b = (buffer_s*) lua_newuserdata(L, sizeof(buffer_s)); 
b->ptr = new buffer;   
b->origin = FROM_LUA;  
luaL_getmetatable(L, "buffer"); 
lua_setmetatable(L, -2); 

现在,当INITING库我还做这样的事情:

luaL_newmetatable(L, "buffer"); //create metatable 
lua_pushcfunction(L,lua_buffer_delete); //push Lua compatible "destructor" 
lua_setfield(L, -2, "__gc"); //place it in the metatable under __gc index 

lua_pushvalue(L, -1); 
lua_setfield(L, -2, "__index"); 

luaL_register(L, NULL, maps_buffer_m); 

现在的Lua将调用__gc元方法免费()之前,荷兰国际集团(由GC)的对象。你可以用它来清理。

我做这样的(部分功能):

if (b->origin == FROM_LUA) 
{ 

    delete b->ptr; //delete the object 
    b->origin = PTR_INVALID; //and mark it as invalid 
    b->ptr = NULL; 
    lua_newtable(L); 
    lua_setmetatable(L, 1);  //set empty metatable, it's not buffer any more 
    return 0; 
} 

我希望它能帮助:)

你可以考虑使用tolua ++或痛饮自动做结合的过程。这将节省大量时间,并可能以正确的方式处理对象的创建和删除。

0

我建议你使用一些Lua Wrapper Class。我一直在我们的项目中使用它,它的工作非常好。它也使事情变得更容易。 当你的Lua脚本结束时,这个类将包装破坏你正在使用释放你的记忆的Lua状态,以及你所有的用户数据。

我还认为,如果你这样做:

lua_close(mState); 

你的用户数据也将被清除。