这是我的代码:
std::list<GameMatch*> games_;
void GameMatchManager::ClearEndedGames()
{
if(games_.empty())
return;
auto it = games_.begin();
while (it != games_.end())
{
auto game = *it;
if(game->MatchEnded())
{
games_.erase(it);
game->Destroy();
}
++it;
}
}
void GameMatch::Destroy()
{
std::cout << "Destoying " << GetMatchId() << std::endl;
delete this;
}
这是我得到的错误:
为什么我在顶部执行if(games.empty()) return;
时,在第一个位置得到这个错误?
这不应该停止games_
列表的迭代吗?为什么我会得到这个错误,我如何修复它?
1条答案
按热度按时间c6ubokkw1#
显而易见的问题是:您使用的迭代器无效。从
std::list
中删除一个元素时,指向other元素的迭代器仍然有效,但被删除元素的迭代器处于未定义状态。一个可能的解决方案是在删除之前迭代一步:其他注解,大多与问题无关:
1.避免使用
Destroy()
等方法;它可能做了一些~GameMatch()
应该做的事情,但是没有来自编译器的与RAII相关的强保证。更喜欢RAII而不是“自制”资源管理。1.不要**使用原始指针。你几乎从来不需要它们。
()唯一的例外是当您实现低级别的链接数据结构时。然后(也只有在那时)使用原始指针才有意义。
1.最好不要直接分配对象(使用智能指针或其他方式)。相反,让STL容器处理分配。直接嵌入对象(
std::list<GameMatch>
而不是std::list<GameMatch*>
)。指针跳跃越少,效率就越高。这里再次使用
ConsumeList()
,这次是在buildable and runnable上下文中:请注意,忘记运行
ConsumeList()
不会在最后导致任何内存泄漏,所有列表元素都将被正确释放。这是使用RAII和避免原始指针的关键优势。