简体   繁体   English

双指针不一致(链接列表)

[英]Inconsistent double pointer (linked list)

I have a game I am working on that uses a linked list for the entities in the game. 我正在开发一个游戏,该游戏使用游戏中实体的链接列表。 I have found what I think to be some sort of bug. 我发现我认为是某种错误。 Note, I'm coding in C. But after this trouble with C pointers I'm thinking about trying C++ techniques. 注意,我正在用C进行编码。但是在使用C指针遇到这种麻烦之后,我正在考虑尝试使用C ++技术。

In my debug testing two projectiles were colliding which blows both of them up. 在我的调试测试中,两个弹丸相撞,炸毁了两个弹丸。 Basically the situation is this: 基本上情况是这样的:

Starting in Entity's move function: 1) Projectile entity moves 2) Loop through all entities checking collision at this new location 3) If collision, in this case between projectiles, remove both 从实体的移动功能开始:1)射弹实体移动2)遍历所有实体,检查在此新位置的碰撞3)如果发生碰撞(在这种情况下,在射弹之间,则将两者都移除)

I pass a double pointer of the entity to the function that does collision. 我将实体的双指针传递给发生冲突的函数。 That entity may be removed but I still need to use it for advancing the entity to the next one in the list (in the while loop). 该实体可能会被删除,但是我仍然需要使用它来将实体推进到列表中的下一个实体(在while循环中)。 If that didn't make sense it is seen as this: 如果那没有意义,则将其视为:

    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
    }

So, I've ran through the code so many times and don't see any illegal operations. 因此,我已经遍历了很多遍代码,没有看到任何非法操作。 The part that gets me is sometimes the double pointer will work and sometimes it won't. 使我感到困惑的部分是双指针有时会起作用,有时却不会。 I tested using a global entity pointer (that always works) to compare back in my entity move function to test if the node being removed matches what it was set to in the entity remove function. 我使用全局实体指针(始终有效)进行了测试,以比较我的实体移动功能,以测试被删除的节点是否与在实体删除功能中设置的节点匹配。

This description is a little abstract, so let me know if I need to explain more. 此描述有点抽象,如果需要进一步说明,请告诉我。

There are zillion solutions which would or would not work for your exact problem. 有成千上万的解决方案无法解决您的确切问题。

Here are some ideas to start with: 以下是一些建议:

  1. Do not delete objects from the container on collision, but mark them "dead". 请勿在碰撞时从容器中删除对象,而是将其标记为“已死”。 Clean up "dead" bodies in separate pass after collision detection finished. 碰撞检测完成后,通过单独的通道清理“死”的物体。
  2. Mark them dead on collision, but not delete at all. 将它们标记为在碰撞时已死亡,但完全不能删除。 Just reuse marked nodes for future entities. 只是将标记的节点重用于将来的实体。
  3. Improvement of (2): sort your container, so "dead" entities went to the tail and mark size of the container as it would contain only "living" ones (2)的改进:对容器进行排序,使“死”实体走到尾部并标记容器的大小,因为它仅包含“活着的”实体
  4. Improvement of (1), (2), (3): implement some kind of "garbage collection", so "dead" entities would be cleaned up let's say once a second or once a frame or when memory threshold reached. (1),(2),(3)的改进:实现某种“垃圾收集”,因此将清理“死”实体,比如说每秒或一次帧或达到内存阈值时。

etc. 等等

Sidenote : You should never use linked lists in 21th's century (an era of hierarchies of caches, prefetching, out-of-order execution and mutithreading), unless you really, really have no other choice and you understand what you are doing. 旁注 :你不应该在21的世纪使用链表(高速缓存层次结构的时代,预取,乱序执行和mutithreading),除非你真的, 真的没有其他选择,你知道你在做什么。 Use arrays by default, swith to something else only if you find it reasonable. 默认使用数组,只有在您认为合理的情况下才使用其他数组。

More info: 更多信息:

Original code: 原始代码:

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!
        */
    }

Sample code using pointer tot pointer: 使用指针tot指针的示例代码:

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

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

        ...
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM