清理内存的 C(++) 和 Lua
2013-4-10 11:35:13
收藏:0
阅读:158
评论:2
我正在使用Lua的C API编写一个应用程序,并且我正在尝试确定我使用它的方式是否会留下一些(指向指针的)悬空指针。
假设我有一个类似于树形结构的结构(实际上是类)在C++中
struct Leaf
{
DoSomeLeafStuff();
List<Leaf*> Children;
};
class Tree
{
public:
Tree() { };
virtual ~Tree()
{
/* 迭代 Children 并删除它们*/
};
void DoSomeTreeStuff();
Leaf getRoot() const { return _root; }
private:
Leaf* _root;
};
- 假设
tree已经创建并包含数据,并且我在Lua中使用它的方式如下:
local root = tree:getRoot()
root:DoSomeLeafStuff()
现在我的Lua中的getRoot()的C实现看起来像:
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的垃圾回收自动清除?
点赞
用户1027550
我建议您使用一些Lua Wrapper Class。我们在项目中一直在使用它,它的效果非常好。它还使事情变得更加容易。
使用这个类时,当 Lua 脚本结束时,包装器会销毁使用的 Lua 状态,释放您的内存和所有用户数据。
我还觉得如果您这样做:
lua_close( mState );
您的用户数据也将被清理。
2013-04-12 09:42:58
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
我正在使用 Lua 包装自己的对象,这是我做的方式:
/*函数的一部分,buffer_s 是一个结构体,它包含指向真实对象及其它一些字段的指针(比如谁创建了这个对象)*/ 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);现在,在初始化库时我也这样做:
luaL_newmetatable(L, "buffer"); //创建元表 lua_pushcfunction(L,lua_buffer_delete); //推入 Lua 兼容的“析构函数” lua_setfield(L, -2, "__gc"); //将其放置在元表的 __gc 索引下 lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); luaL_register(L, NULL, maps_buffer_m);现在 Lua 将在释放对象之前调用 __gc 元方法。您可以使用它进行清理。
我这样做(函数的一部分):
if (b->origin == FROM_LUA) { delete b->ptr; //删除对象 b->origin = PTR_INVALID; //将其标记为无效 b->ptr = NULL; lua_newtable(L); lua_setmetatable(L, 1); //设置空元表,这不再是 buffer return 0; }希望这有所帮助 :)
您可以考虑使用 tolua++ 或 swig 自动化绑定过程。它将节省大量时间,并且可能会正确处理对象的创建和删除。