c++ - std::list 和垃圾收集算法
问题描述
我有一台服务器,可根据要求将 2 名玩家放在一起,并Game
在新线程中开始游戏。
struct GInfo {Game* game; std::thread* g_thread};
while (true) {
players_pair = matchPlayers();
Game* game = new Game(players_pair);
std::thread* game_T = new std::thread(&Game::start, game);
GInfo ginfo = {game, game_T}
_actives.push_back(ginfo); // std::list
}
我正在编写一个在另一个线程中运行的“垃圾收集器”,以清除已终止游戏的内存。
void garbageCollector() {
while (true) {
for (std::list<Ginfo>::iterator it = _actives.begin(); it != _actives.end(); ++it) {
if (! it->game->isActive()) {
delete it->game; it->game = nullptr;
it->g_thread->join();
delete it->g_thread; it->g_thread = nullptr;
_actives.erase(it);
}
}
sleep(2);
}
}
这会产生一个段错误,我怀疑这是因为_active.erase(it)
处于迭代循环中。为了进行故障排除,我做了_actives
一个std::vector
(而不是std::list
)并应用了相同的算法,但使用索引而不是迭代器,它工作正常。
有没有解决的办法?
算法、数据结构用的好吗?有没有更好的垃圾收集方法?
帮助表示赞赏!
解决方案
如果您查看erase方法的文档,它会在被删除的元素之后返回一个迭代器。
使用它的方法是将返回的值分配给您的迭代器,就像这样。
for (std::list<Ginfo>::iterator it = _actives.begin(); it != _actives.end();) {
if (! it->game->isActive()) {
delete it->game; it->game = nullptr;
it->g_thread->join();
delete it->g_thread; it->g_thread = nullptr;
it = _actives.erase(it);
}
else {
++it;
}
}
由于从获取返回值erase
将迭代器推进到下一个元素,因此我们必须确保在发生这种情况时不要增加迭代器。
在不相关的注释中,以下划线开头的变量名称通常保留给编译器的内部,应该在您自己的代码中避免使用。
推荐阅读
- r - 使用存储在列表中的数据帧内的 table() 创建新的数据帧
- javascript - 用 Javascript 编译 Latex
- html - 淘汰赛 JS 复选框列表不绑定
- php - 逐张从excel文件中提取数据。单工lsx
- c - Different ways of suppressing 'uninitialized variable warnings' in C
- c++ - Why is a member in a primary class template not declared in the scope of the specialized class?
- docker - Docker compose:需要一个映射或映射列表以进行合并,但找到了标量
- javascript - 防止android webview中的无效输入值更改
- javascript - 如何使用 javascript 获取附加的部分 url
- angular - Angular 8 & Laravel echo websockets with socket io:找不到 Socket.io 客户端