我正在用C ++编写我的在线应用程序。最近我需要为游戏编写一个技能系统,其中一次执行的技能将5波相同的效果放在一起,每波延迟0.5秒。我想出了使用线程和睡眠功能的想法,以防止其他玩家冻结。
所以我的代码看起来像这样:
struct monster_skill_info
{
monster_skill_info(IMonster *_m, ICharacter *_o) : m(_m), o(_o) {}
IMonster *m;
ICharacter *o;
};
void FireStorm(PVOID v)
{
INTERFACE(Monster)
IMonster *m = ((monster_skill_info*)v)->m;
ICharacter *o = ((monster_skill_info*)v)->o;
for (int i = 0; i < 5; i++)
{
// magic happens here
Sleep(500);
}
}
void ISkill::FireStorm(IMonster* m, ICharacter* o)
{
_beginthread(::FireStorm, 0, (void*)(new monster_skill_info(m, o)));
}
问题是,经过24小时的正常运行时间线程停止工作。没有技能可以执行。我确定_beginthread停止了它的工作。它很难调试,因为它发生在24小时甚至更长时间之后。是否有可能_beginthread在一段时间后停止工作?我可以用这个做点什么吗?
delete v;
功能结束后我应FireStorm(PVOID v)
吗?可能是内存泄漏问题?
答案 0 :(得分:1)
此处有内存泄漏
void ISkill::FireStorm(IMonster* m, ICharacter* o)
{
_beginthread(::FireStorm, 0, (void*)(new monster_skill_info(m, o)));
}
每次在C ++中使用new时都必须删除它,可以使用
monster_skill_info{m,o}; // vs (new monster_skill_info(m, o))
而raii会在超出范围时自动将其删除
Remenber,如果你分配,你必须永远解除分配
答案 1 :(得分:1)
_beginthread可能会在一段时间后停止工作吗?
本身,不太可能。但是,由于系统已经进入某些条件,它可能会失败。
我能用这个做点什么吗?
第一道防线是检查_beginthread
的返回,从而实际看看你认为它不起作用的想法是否有价值。如果失败,请检查失败的原因(errno
),您可能知道该怎么做。如果它没有失败,请尝试另一个想法。
当然,将其写入某些日志,不要在调试器中执行此操作。
我应该删除v;在FireStorm(PVOID v)功能结束时?可能是内存泄漏问题?
是的,您应该在v
结束时删除FireStorm
,或在完成使用后的某个时间点删除beginthread
。你是在泄漏记忆,经过一段时间后这肯定是个问题。
例如,您的系统可能会变得非常慢,因为它会使很多虚拟机“肆无忌惮”。因此,假设from itertools import chain, combinations
def powerset_generator(i):
for subset in chain.from_iterable(combinations(i, r) for r in range(len(i), -1, -1)):
yield list(subset)
可能实际上不会失败,只需花费长时间即可完成。