Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Lua:这会导致SEGA故障吗_C++_Lua - Fatal编程技术网

C++ Lua:这会导致SEGA故障吗

C++ Lua:这会导致SEGA故障吗,c++,lua,C++,Lua,我正在开发一个使用Lua编写脚本的程序,有时它会崩溃。对于GDB,我想我发现了问题,但我不知道它是否解决了问题,因为SEGDB故障只会偶尔出现。所以,旧代码是这样的: 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)) ) { i

我正在开发一个使用Lua编写脚本的程序,有时它会崩溃。对于GDB,我想我发现了问题,但我不知道它是否解决了问题,因为SEGDB故障只会偶尔出现。所以,旧代码是这样的:

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;
        }
    }
}
而断层也不再发生了。这可能是问题所在吗?

根据,您有责任保持堆栈清洁,因为Lua不会执行任何检查。我将假设segfault是不保持堆栈干净的合理结果(新值被推送到实际堆栈空间之外的内存位置,顺便说一下,也在进程虚拟内存之外)

由于不调用lua_pcall来从堆栈中删除non函数,这将无限期地增长堆栈

除非被调用的函数在堆栈上留下一些东西,否则您的解决方案应该是有效的。 由于将nresults设置为0,Lua不会在堆栈上留下任何结果

但是,我对lua_pcall引用的理解是,即使nresults为0,错误代码也可以留在堆栈上。编辑:我也检查了那个行为,它和我想象的一模一样

在这种情况下,在开始时调用lua_gettop,在结束时调用lua_settop在任何情况下都会起作用,并保持堆栈的平衡。

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


您可以在中看到:对于每个函数,它在描述中都有详细说明,并且在函数原型旁边的括号中以灰色表示。例如,has[-0,+1,e]表示它不会弹出任何元素,并且(总是)推送一个元素(e表示它可能会导致错误).

应该指出的是,在Lua->C转换时,Lua确保您有一个新的堆栈,而在C->Lua转换时,Lua确保堆栈从您可能留在堆栈上的任何东西中清理出来,因此不需要在这些点进行平衡(尽管这可能仍然是一个良好的做法)。但是,只要您使用C语言,就需要堆栈管理(和函数堆栈平衡)。
lua_pop(L,lua_gettop(L));