我有一段代码运行了很多次,突然报告访问冲突。
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()
方法在成功之前执行了几次,但突然它不再起作用了。
会不会是地址改了?我覆盖了吗?
请帮帮我!另外,我很欣赏有关此代码不合适的任何信息:)
最佳答案
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(现为 Freescale)Codewarrior 定义了 _MSL_DEBUG
,例如,它可用于构建标准库版本(包括 std::list
),它将检测迭代器失效等常见问题(以某些运行时成本为代价)。
看起来 Visual Studio 有 debug iterator support如果您正在使用它,这可能符合要求。
关于c++ - 调用非虚拟成员函数时发生访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8626128/