Lua:这会导致段错误

Dir*_*irk 6 c++ lua

我正在开发一个使用Lua编写脚本的程序,有时它会崩溃.使用GDB我认为我发现了问题,但我不知道它是否解决了它,因为段错误只会偶尔发生.所以,旧代码是这样的:

void Call(std::string func){
    lua_getglobal(L, func.c_str()); //This is the line GDB mentioned in a backtrace
    if( lua_isfunction(L,lua_gettop(L)) ) {
        int err = lua_pcall(L, 0, 0,0 );
        if(err != 0){
            std::cout << "Lua error: " << luaL_checkstring(L, -1) << std::endl;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,这个函数每秒会被调用几次,但它需要调用的函数并不总是被定义,所以我认为堆栈会溢出.我添加了以下行:

lua_pop(L,lua_gettop(L));
Run Code Online (Sandbox Code Playgroud)

并且不再发生段错误了.这可能是问题吗?

Obe*_*ron 5

使用lua_gettop(L)作为参数lua_pop将清除整个Lua API堆栈(它相当于lua_settop(0)),这可能不是您想要的.但确实你的问题是lua_getglobal总是推动一些东西; 如果不存在具有给定名称的全局,则它会推送nil,就像等效的Lua表达式一样.但是,lua_pcall弹出函数和所有参数(如果有的话;在您的情况下,您指定为零),因此如果函数存在,您将不会遇到问题.你应该做的是增加外部的lua_pop(L, 1)一个else条款if.这样,您的功能将始终保持平衡(即保持堆栈不变).

你可以在Lua手册中看到这些东西:对于每个函数,它都在描述中拼写出来,并在函数原型旁边的括号中用灰色表示.例如,lua_getglobal有[-0,+ 1,e]意味着它不会弹出任何元素,并且(总是)推送一个元素(并且e意味着它可能导致错误).