我有一些代码运行了很多次,并突然报告访问冲突。
for(std::list<Projectile>::iterator it = projectiles.begin(); it != projectiles.end();) {
bool finished = ...
// try to print address of collides(), prints always 1
std::cout << &Projectile::collides << std::endl;
// here it crashes:
if(it->collides(&hero)) {
std::cout << "Projectile hits " << hero.getName() << std::endl;
finished = it->apply(&hero);
}
// ...
if(finished) {
it = projectiles.erase(it);
} else {
++it;
}
}
因此,VS调试堆栈跟踪表示在行if(it->collides(&hero)) {
中,程序尝试调用cdcdcdcd()
处的方法,这会导致访问冲突。
it
,*it
和hero
是有效对象。
所以我假设cdcdcdcd()
实际应该是collides()
。由于collides是一种非虚方法,它的地址基本上不应该改变或者?
问题是方法collides()
在成功之前执行了好几次,但突然间它不再起作用了。
地址是否可以更改?我覆盖了吗?
请帮帮我!此外,我感谢有关此代码不正常的任何信息:)
答案 0 :(得分:2)
0xcdcdcdcd
是Win32 Debug CRT Heap使用的填充模式;假设您在Windows上运行调试器,这可能是一个重要的线索。有一个不错的explanation of the heap fill patterns here。
我的猜测是你在某种程度上要么在其他地方使迭代器无效,要么有其他缓冲区溢出或悬空指针或其他问题。
Application Verifier可能有助于诊断这一点。您可能还想查看问题How to debug heap corruption errors?中提到的其他内容或Any reason to overload global new and delete?中的一些技巧(免责声明:目前我对两者都有最高评价的答案)。
如果您的STL库具有调试功能,它也可能有助于解决这个问题。 Metrowerks(现在飞思卡尔)Codewarrior有定义_MSL_DEBUG
,例如,它可用于构建标准库的版本(包括std::list
),它将检测迭代器失效等常见问题(在某些运行时)成本)。
如果您使用的话,Visual Studio的debug iterator support可能符合要求。
答案 1 :(得分:0)
你的终止条件似乎错了 [编辑:实际上它看起来是正确的,即使它仍然让我害怕。见评论。] 。当finished
变为真时,你擦除当前的射弹,然后将迭代器设置为......某事。没有理由认为循环将在此时终止。 it
最终可能会开始指向列表之外,或者指向其他无效对象(调试器不会始终标记为此对象)。
当您擦除射弹时,您应该使用“break”明确地离开循环。