Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/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/C++;-在lua_next()内尝试行走桌子时出现SEGFULT_C++_Lua_Segmentation Fault - Fatal编程技术网

C++ Lua/C++;-在lua_next()内尝试行走桌子时出现SEGFULT

C++ Lua/C++;-在lua_next()内尝试行走桌子时出现SEGFULT,c++,lua,segmentation-fault,C++,Lua,Segmentation Fault,我有以下C++代码: lua_getglobal(C, "theTable"); lua_pushnil(C); while (lua_next(C, -2) != 0) { /* snip */ } 但是,当它运行时,会报告segfault。LLDB stop消息如下所示 * thread #1: tid = 0x50663f, 0x000000000002b36a luaos`luaH_next + 58, queue = 'com.apple.main-thread', stop r

我有以下C++代码:

lua_getglobal(C, "theTable");
lua_pushnil(C);
while (lua_next(C, -2) != 0) {
  /* snip */
}
但是,当它运行时,会报告segfault。LLDB stop消息如下所示

* thread #1: tid = 0x50663f, 0x000000000002b36a luaos`luaH_next + 58, queue =
'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x38)
frame #0: 0x000000000002b36a luaos`luaH_next + 58
Luaos是可执行文件名。为了便于移植,我将Lua直接编译到可执行文件中


p.S.
C
是lua州的名称。这是我的二次配置lua状态(与我的主代码lua状态相反),这就是名称背后的原因。

我发现三个潜在问题:

  • 全局变量
    表格
    不存在,并且在
    -2
    位置有零

  • 在循环中使用
    lua\u tostring
    将键转换为字符串,可能是为了打印。这会混淆的手册
    lua\u next

  • 在第一次循环迭代之后,在位置
    -2
    处还有一些其他值。请注意,
    lua_next
    将两个值推送到堆栈上,即键和值。在再次调用
    lua\u next
    之前,需要将键保留在堆栈顶部。您需要确保工作台保持在位置
    -2
    。在
    lua\u getglobal
    之后使用
    lua\u gettop
    -2
    转换为绝对位置可能更安全。但是,在每次迭代之后,仍然需要将
    lua_next
    返回的密钥保留在堆栈顶部


似乎您的代码只是部分正确,我将详细解释如何使用
lua\u next
,甚至您的代码正确执行的部分。
lua_next
要求堆栈中至少有两个元素(按以下顺序):

在对函数的第一次调用中,
previous key
应该是
nil
,因此函数将把第一对键值推送到堆栈中,遍历将开始

lua_getglobal(L, "theTable"); // Stack table
// ...
lua_pushnil(L);               // Push nil
lua_next(L, t);               // t is theTable index
当调用
lua\u next
时,弹出上一个键并将键值对推送到堆栈中,因此它看起来像这样:

[1] value
[2] key
...
[t] -- unknown value --
[t+1] table
如果使用此堆栈再次调用该函数,它将作为当前键的输入
,作为
表的未知值
,因此将出现错误。为避免弹出堆栈顶部(
[1]值

lua_pop(L, 1); // Pop value
现在堆栈将具有继续遍历的预期值,并且可以再次调用
lua\u next
。 当表中没有更多元素时,函数将返回0。
下面是一个完整的示例:

lua_getglobal(L, "theTable"); // Stack table
lua_pushnil(L);               // Push nil
while(lua_next(L, -2) != 0) {
    // Do something with key, value pair
    lua_pop(L, 1); // Pop value
}

你在你的圈子里做什么?您是在向堆栈中添加元素而不是清理它们吗?你在改变你正在走过的桌子吗?每次通过循环,我都会把一些元素推到堆栈上,但之后我会把它们清理干净。我也有95%的把握,问题出在循环的第一次迭代中。你是将密钥留在堆栈的末尾,还是在无意中清理了它?如果对表使用正索引,是否会发生崩溃?我没有想到意外删除键会有什么影响。是的,如果我使用正指数,就会发生这种情况。你是在循环中使用
lua\u tostring
?这可能会混淆手册中提到的
lua_next
lua_getglobal(L, "theTable"); // Stack table
lua_pushnil(L);               // Push nil
while(lua_next(L, -2) != 0) {
    // Do something with key, value pair
    lua_pop(L, 1); // Pop value
}