Lua / C ++ - 在试图走路表时,在lua_next()里面的Segfault

时间:2014-09-15 20:01:31

标签: c++ lua segmentation-fault

我在C ++中有以下代码:

lua_getglobal(C, "theTable");
lua_pushnil(C);
while (lua_next(C, -2) != 0) {
  /* snip */
}

但是,当它运行时,会报告段错误。 LLDB停止消息如下。

* 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状态L),这就是名称背后的原因。

2 个答案:

答案 0 :(得分:4)

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

[1] previous key
...
[t] table

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

lua_getglobal(L, "theTable"); // Stack table
// ...
lua_pushnil(L);               // Push nil
lua_next(L, t);               // t is theTable index

当调用lua_next弹出上一个键并将一个键值对推送到堆栈时,它看起来像这样:

[1] value
[2] key
...
[t] -- unknown value --
[t+1] table

如果使用此堆栈再次调用该函数,它将具有作为当前键的输入value和作为table的未知值,因此将出现错误。为了避免应该弹出堆栈的顶部([1] value

lua_pop(L, 1); // Pop value

现在堆栈将具有继续遍历的预期值,并且可以再次调用lua_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
}

答案 1 :(得分:0)

我发现了三个潜在的问题:

  • 全局变量theTable不存在,位置-2为零。

  • 您在循环中使用lua_tostring将键转换为字符串,可能用于打印。手册says混淆了lua_next

  • 在第一次循环迭代后,您在位置-2处有一些其他值。请注意,lua_next将两个值推送到堆栈,键和值。在再次调用lua_next之前,您需要将密钥保留在堆栈顶部。您需要确保表格保持在-2位置。在-2之后将lua_gettop转换为lua_getglobal的绝对位置可能会更安全。但是,在每次迭代后,您仍然需要将lua_next返回的密钥保留在堆栈顶部。