gpt4 book ai didi

c++ - 如何使用 delete 运算符释放 lua_newuserdata 分配的内存?

转载 作者:太空狗 更新时间:2023-10-29 19:52:40 26 4
gpt4 key购买 nike

如何释放 lua_newuserdata 分配的内存?

我有一个名为Foo的类,这个类有一个构造函数和一个析构函数,我需要同时执行这两个,但我不知道如何使用C++运算符delete,因为我没有使用new来分配内存。

我尝试在创建对象的 Lua 函数 new 中这样做:

Foo *pf = reinterpret_cast<Foo *>(
lua_newuserdata(L, sizeof(Foo)));

我在 gc 函数中尝试过:

Foo *foo = reinterpret_cast<Foo *>(lua_touserdata(L, 1));
delete foo;

但我遇到了段错误。

最佳答案

在这种情况下,您需要使用一个名为 userdatum 的 lua 概念,这意味着,您需要使用 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;
}

关于c++ - 如何使用 delete 运算符释放 lua_newuserdata 分配的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21792657/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com