如何使用 delete 运算符释放由 lua_newuserdata 分配的内存?
2014-2-15 2:40:3
收藏:0
阅读:102
评论:2
如何释放 lua_newuserdata 分配的内存?
我有一个名为 Foo 的类,这个类有一个构造函数和析构函数,我需要执行两者,但是我不知道如何使用 C++ 运算符 delete,因为我没有使用 new 分配内存。
我尝试在创建对象的 Lua 函数中执行:
Foo *pf = reinterpret_cast<Foo *>(
lua_newuserdata(L, sizeof(Foo)));
在 GC 函数中我也尝试了这样做:
Foo *foo = reinterpret_cast<Foo *>(lua_touserdata(L, 1));
delete foo;
但我得到了一个分段错误。
点赞
用户3988443
C++删除对象有两个步骤,运行析构函数和释放动态分配的内存。如果调用lua_newuserdata来为对象分配存储空间,则可以使用放置的new在Lua分配的内存空间中运行构造函数,并且可以使用Lua垃圾收集"__gc"方法显式地调用对象的析构函数,例如"pMyObject->~MyClass ()"。然而,存储回收(释放lua_newuserdata动态分配的内存)由Lua环境自动处理,因此在"__gc"方法中调用delete会导致软件失败。如果内存由Lua分配,则应该由Lua一致地释放。
2019-06-27 15:16:47
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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概念称为userdatum,意思是您需要使用lua_newuserdata来分配一个指向对象的指针。
分配内存可以做这样的事情:
Foo **pfoo = reinterpret_cast<Foo **>(lua_newuserdata(L, sizeof(Foo*))); *pfoo = new Foo(foo);在垃圾收集器函数中,您可以这样做:
Foo **foo = reinterpret_cast<Foo **>(lua_touserdata(L, 1)); delete *foo;下面是一个完整的代码示例,使用了userdatum的概念
#define FOO "foo" class Foo { public: Foo(const char *name) { this->name = (char *) malloc(strlen(name) + 1); strncpy(this->name, name, strlen(name)); } Foo(const Foo &obj) { this->name = (char *) malloc(strlen(name) + 1); strncpy(this->name, obj.name, strlen(obj.name)); } const char* get_name() const { return this->name; } ~Foo() { free(this->name); } private: char *name; }; static Foo* push_foo(lua_State *L, Foo foo) { Foo **pfoo = reinterpret_cast<Foo **>( lua_newuserdata(L, sizeof(Foo*))); *pfoo = new Foo(foo); luaL_getmetatable(L, FOO); lua_setmetatable(L, -2); return *pfoo; } static Foo* chk_foo(lua_State *L, int index) { Foo *foo; luaL_checktype(L, index, LUA_TUSERDATA); foo = *reinterpret_cast<Foo **>(luaL_checkudata(L, index, FOO)); if (foo == NULL) luaL_error(L, "error"); return foo; } static int foo_new(lua_State *L) { int argc = lua_gettop(L); if(argc != 1) luaL_error(L, "string argument expected"); const char* str = luaL_checkstring(L, 1); push_foo(L, Foo(str)); luaL_getmetatable(L, FOO); lua_setmetatable(L, -2); std::cout << "Lua object created!" << std::endl; return 1; } static int foo_get(lua_State *L) { Foo *foo = chk_foo(L, 1); luaL_argcheck(L, foo != NULL, 1, "Error foo"); lua_pushstring(L, foo->get_name()); return 1; } static int foo_gc(lua_State *L) { Foo **foo = reinterpret_cast<Foo **>(lua_touserdata(L, 1)); luaL_argcheck(L, *foo != NULL, 1, "Error foo"); delete *foo; std::cout << "Lua GC executed!" << std::endl; return 0; } int luaopen_foolib(lua_State *L) { static const luaL_Reg Obj_lib[] = { { "get", &foo_get }, { NULL, NULL } }; static const luaL_Reg LuaLib_Foo[] = { { "new", &foo_new }, { NULL, NULL } }; luaL_newlib(L, LuaLib_Foo); // Stack: MyLib luaL_newmetatable(L, FOO); luaL_newlib(L, Obj_lib); lua_setfield(L, -2, "__index"); lua_pushstring(L, "__gc"); lua_pushcfunction(L, foo_gc); lua_settable(L, -3); lua_pop(L, 1); return 1; } int main(int argc, char **argv) { lua_State *L; L = luaL_newstate(); luaL_openlibs(L); luaL_requiref(L, "foo", &luaopen_foolib, 1); lua_pop(L, 1); const char *code = "f = foo.new(\"my_test\")\nprint(f:get())"; if(luaL_loadstring(L, code) != 0) { std::cout << "Could not load: " << argv[1] << std::endl; exit(EXIT_FAILURE); } if(lua_pcall(L, 0, 0, 0) != 0) { std::cout << "Error: " << lua_tostring(L, -1) << std::endl; lua_pop(L, 1); exit(EXIT_FAILURE); } lua_close(L); return 0; }