lua C api: 如何遍历一个表格而没有可能出现 lua_error / lua panic?

在 lua 5.2 的手册中有一些关于 lua_next 的文档,这是用于迭代表格的函数。

典型的遍历代码如下:

 /* 表格是栈中的索引 't' */
 lua_pushnil(L);  /* 第一个键 */
 while (lua_next(L, t) != 0) {
   /* 使用 'key' (栈中索引 -2) 和 'value' (栈中索引 -1) */
   printf("%s - %s\n",
          lua_typename(L, lua_type(L, -2)),
          lua_typename(L, lua_type(L, -1)));
   /* 弹出 'value',保留 'key' 用于下一次迭代 */
   lua_pop(L, 1);
 }

根据手册,此示例中的 C api 调用除了 lua_next 以外都不会导致 lua 错误 (lua_typelua_typenamelua_pushnillua_pop)。

据我所理解,lua_next 只有在分配内存失败的情况下才会导致错误,因此这只是在希望从内存分配失败中恢复的程序中才有问题。

然而,假设我正在编写这样一个程序。如果我想要从这样的错误中恢复,是否有一种方法可以避免将上述迭代代码放在受保护的调用中?

据我所理解,lua_next 实际上不应该复制任何内容。堆栈上的内存已经分配,并将原子值分配给堆栈位置不会导致 lua 分配更多的内存。在字符串的情况下,lua 是写时复制的。在引用值的情况下,它只会增加引用计数器,不需要动态分配。

假设我首先放置了 lua_checkstack(L, 2) 来确保有两个条目(keyvalue)的堆栈空间。这足以保证我不会有 lua 错误,因此可以避免将其置于受保护的上下文中吗?(忘记手册上说了什么。)到底 lua 在这里需要执行哪些动态分配?

点赞