不一致的双指针(链表)

时间:2015-03-12 11:57:31

标签: c list pointers linked-list

我正在制作一款游戏,它使用游戏中实体的链接列表。我发现了我认为是某种bug。注意,我在C编码。但在使用C指针的麻烦后,我正在考虑尝试C ++技术。

在我的调试测试中,两个射弹发生碰撞,这两个射弹都将两个射弹击中。基本上情况是这样的:

从实体的移动功能开始: 1)弹丸实体移动 2)遍历检查此新位置处的冲突的所有实体 3)如果发生碰撞,在这种情况下发射射弹,则将两者都移除

我将实体的双指针传递给执行碰撞的函数。可以删除该实体,但我仍然需要使用它来将实体推进到列表中的下一个实体(在while循环中)。如果这没有意义,就会被视为:

    ENTITY *node;

    while (node)
    {
        ...

        entity_do_collision (&node); // <-- node may be removed in this function

        //Debug
        if (node == global_node)
        {
        }
        else
            node = global_node;

        node = node->next; // <-- pass a double pointer above so this works here
    }

所以,我已经多次查看代码并且没有看到任何非法操作。得到我的部分有时是双指针可以工作,有时它不会。我测试了使用全局实体指针(总是有效)来比较我的实体移动函数,以测试被删除的节点是否与实体移除函数中设置的相匹配。

这个描述有点抽象,所以如果我需要解释更多,请告诉我。

2 个答案:

答案 0 :(得分:2)

有许多解决方案对您的确切问题有效或无效。

以下是一些想法:

  1. 不要在碰撞时从容器中删除对象,但要标记它们&#34; dead&#34;。清理&#34;死了&#34;碰撞检测完成后,单独通过的物体。
  2. 碰撞时将它们标记为死亡,但根本不删除。只需为未来的实体重复使用标记的节点。
  3. (2)的改进:对容器进行分类,以及&#34;死亡&#34;实体去了尾巴并标记了容器的大小,因为它只包含&#34; living&#34;那些
  4. (1),(2),(3)的改进:实施某种&#34;垃圾收集&#34;所以&#34;死&#34;实体将被清理,让我们说一次或每帧一次或达到内存阈值。
  5. Sidenote :在21世纪(高速缓存,预取,无序执行和多线程的层次结构的时代),你永远不应该使用链表,除非你真的,< em>真的别无选择,你明白自己在做什么。默认情况下使用数组,只有在发现合理的情况下才开始使用数组。

    更多信息:

答案 1 :(得分:0)

原始代码:

ENTITY *node;

    while (node)
    {
        ...

        entity_do_collision (&node); // <-- node may be removed in this function
        node = node->next;
        /* the function can have changed node's value
        ** but on the next iteration ( on the **value** of node->next)
        ** the original node->next will not be affected!
        */
    }

使用指针指针的示例代码:

ENTITY **pp;
for (pp = &global_node; *pp; pp = &(*pp)->next)
    {
        ...

        entity_do_collision (pp); // <-- *pp  (= node) may be removed in this function

        ...
    }