随机循环访问映射会导致段错误
Iterating through a map randomly causes segfault
我一直在努力解决一个相当令人困惑的问题:当我的实体管理器遍历更新循环中的实体映射时,我偶尔会遇到分段错误。奇怪的是,这种情况并非一直发生;有时它会在加载时崩溃,有时我可以在应用程序状态之间切换(并多次加载和卸载实体)几次,然后再出现段错误。在调试模式下,我似乎也得到了更多的段错误。我的实体由指向行为和可绘制对象类的指针组成。
段错误后的调用堆栈:
#0 6FCB4986 libstdc++-6!_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base() (C:MinGWbinlibstdc++-6.dll:??)
#1 0040A1D7 std::_Rb_tree_iterator<std::pair<unsigned int const, Entity*> >::operator++(this=0x28fe94) (c:/mingw/bin/../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:196)
#2 00401F55 EntityManager::onLoop(this=0x417238) (C:UsersNelariusDocumentsKurssitMiinaharavasrcengineEntityManager.cpp:75)
#3 00401640 App::onLoop(this=0x417040) (C:UsersNelariusDocumentsKurssitMiinaharavasrcengineApp.cpp:38)
#4 0040160C App::execute(this=0x417040) (C:UsersNelariusDocumentsKurssitMiinaharavasrcengineApp.cpp:30)
#5 00403BD7 main(argc=1, argv=0x642908) (C:UsersNelariusDocumentsKurssitMiinaharavasrcmain.cpp:15)
这是我的更新循环:
void EntityManager::onLoop()
{
std::map<const unsigned int, Entity*>::iterator it;
for (it = _gameObjects.begin(); it != _gameObjects.end(); it++)
{
Behavior* behavior = it->second->getBehavior();
if (behavior)
{
behavior->update();
}
}
}
我得到段错误在
for (it = _gameObjects.begin(); it != _gameObjects.end(); it++)
顺便问一下,当我不使用任何多线程时,有两个线程是否正常?我正在查看Code::Blocks
调试窗口,碰巧看到线程监视窗口中有两个线程(尽管只有一个线程处于活动状态)。
这种事情归结为behavior->update()
能够通过一系列嵌套函数调用来生成正在修改的_gameObjects
容器(例如,如果在游戏对象中检测到的某些条件导致出于任何原因创建或删除游戏对象)。
如果您从map
中删除了一个元素,这可能会使您的迭代器无效并破坏您的循环,并且很难在这样的"内核"代码中发现。
常见的解决方案是复制循环的游戏对象列表。当然,您不会复制对象本身,但您可以保护它们的列表在更新运行过程中不被改变。
它在调度方面也"更公平"——你基本上避免了心怀不满的自我复制游戏对象发起DDoS攻击的可能性。 :)
您正在迭代非本地数据,然后调用非本地函数。
创建本地地图。 将类映射swap
其中。 遍历该本地地图。 断言在迭代完成后类映射被更改(您还需要断言所有从类映射中删除内容的尝试都成功)。
然后将本地映射交换回类的映射。
这将告诉您崩溃是否由您的不良设计引起。 即使这不会生成任何断言,设计仍然存在问题,因为远离上述代码的无害代码更改可能会导致出现上述问题:代码正确性的非局部性会导致问题。 通过充分的测试,可以容忍断言代码正确性的非局部性。
一般回调问题要求您对注册回调的含义做出妥协,并涉及以类似于多线程代码的方式思考问题。 如果您不愿意妥协,代码复杂性可能会变得非常高。 建议使用智能指针来简化事情。
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 如何摆脱C ++中的分段错误错误?
- Clang 8 带有静态 constexpr 和数组的链接器错误 - 错误是什么以及如何解决它?
- 为什么每当我尝试运行此链接列表删除功能时都会收到分段错误错误?
- 如何解决分段错误错误C++
- 作为参数模板的模板类:MSVC 错误 - 错误 C2977:模板参数过多 (C++98)
- 安卓工作室 |CPP 文件错误错误: 位图库中对"AndroidBitmap_unlockPixels"的未定义引用
- 卷曲给出分段错误错误
- 无法访问 Arduino 结构字段。错误"退出状态 1。xxxx 不命名类型"
- 错误错误 C2872:"布尔值":kinect.h 的不明确符号
- C++打印模板容器错误(错误:"运算符<<"的不明确重载)理解?
- 结构的分割错误错误
- 为什么此代码返回分段错误错误?
- 错误错误:无法编译内置功能
- 分段错误错误C++
- C++ 1Z 错误:错误:演绎指南中声明中的显式限定
- 使用对数据类型的向量的哈希表中的分段错误错误
- 为什么此代码会导致分段错误错误
- JNA结构字段值错误
- C++段故障错误