【问题标题】:Detect infinite loops in lua table crawling检测lua表爬行中的无限循环
【发布时间】:2013-06-26 14:28:43
【问题描述】:

我正在尝试使用 lua c api 浏览全局命名空间及其所有内容。我遇到的一个问题是表格中的自我引用。我使用扁平表方法来确定是否存在条目,但这对于嵌套数字表失败,例如:

a = {[1] = {[1]={[1]=true}}}

其中 1 的键名将错误地触发重复条目,因为它出现多次。为了避免这种情况,我采用了使用 lua_topointer 并将引用存储在映射中并像这样检查的方法(其中 varUnit 只是一个跟踪已加载变量的结构):

    lua_pushvalue(L, -1);
    const void* kp = lua_topointer(L, -1);
    var->kpointer = kp;
    varUnit->addPointer(kp);
    lua_pop(L, 1);
    lua_pushvalue(L, -2);
    const void* vp = lua_topointer(L, -1);
    var->vpointer = vp;
    varUnit->addPointer(vp);
    lua_pop(L, 1);

然后我稍后检查该变量是否存在,如果存在,我就停止走下桌子。但是,在处理自引用表时,这并没有阻止无限递归。这里有更好的方法/一些有缺陷的逻辑吗?给定表的第二次相遇会给我一个不同的指针吗?我见过多种基于 lua 的爬取表的方法,但不是任何基于 c 的。

编辑: 关闭的问题,是一个愚蠢的错误,我在将指针分配给变量之前检查指针是否重复。

【问题讨论】:

    标签: c api recursion lua self-reference


    【解决方案1】:

    我不确定您所说的“使用扁平表格方法”是什么意思;但是在您的代码中的某处,您必须检查给定值是否是一个表格(以便您可以在其中检查)。最简单的方法是保留一组所有已访问过的表,对于您找到的表,首先检查它是否已经存在,这样您就不会对其进行两次爬网。

    【讨论】:

    • 这不起作用。上面示例的扁平表类似于: (a,1,1,1) 表示最右边的表。这失败了,因为键名不是唯一的。这就是我使用指针的原因,因为我假设每个值都有一个唯一且持久的(针对当前范围)指针,但由于我不知道的原因,它不起作用。
    • AFAICT,“扁平表”(无论这意味着什么)不能有循环。你自己把它们弄平吗?或者你已经把它们弄平了?如果是第一个,那么您应该在哪里检测循环(或者展平不会成功);如果是后者,那应该不是你的问题。
    猜你喜欢
    • 2012-10-14
    • 2014-04-12
    • 1970-01-01
    • 2012-05-08
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多