我正在制作一款游戏,它使用游戏中实体的链接列表。我发现了我认为是某种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
}
所以,我已经多次查看代码并且没有看到任何非法操作。得到我的部分有时是双指针可以工作,有时它不会。我测试了使用全局实体指针(总是有效)来比较我的实体移动函数,以测试被删除的节点是否与实体移除函数中设置的相匹配。
这个描述有点抽象,所以如果我需要解释更多,请告诉我。
答案 0 :(得分:2)
有许多解决方案对您的确切问题有效或无效。
以下是一些想法:
等
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
...
}