问题描述
我正在为游戏编写派对系统,我从包含派对 IP 地址的 std::set std::wstring 中得到了一些非常奇怪的行为。我得到的错误是在 xtree 中,通常是清晰的,但我也在插入中遇到了它。这是 _Head->_Parent 的读访问冲突,通常会说“_Head->_Parent 是 [内存地址]。”
这个问题非常罕见,我已经尝试重现它2个月了,但没有成功。游戏 24/7 每天都在创建和销毁数以千计的派对,而我每周只收到 2-3 次这个错误。插入、擦除、迭代或清除此集合的所有内容周围都有一个全局互斥锁,仅用于此集合。相关代码如下:
Party.h
```
private:
std::set<std::wstring> ipList;
public:
std::set<std::wstring> getIPList() { return ipList; }
```
Party.cpp
```
PartyManager::disbandParty(Party* party){
SAFE_DELETE(party);
}
Party::~Party(){
ipList.clear();
}
Party::AddPartyMember(){
getUniquePlayerLock.lock();
ipList.insert(s2ws(player->GetClientSession()->GetRemoteIP()));
getUniquePlayerLock.unlock();
}
Party::LeaveParty(){
getUniquePlayerLock.lock();
ipList.erase(s2ws(player->GetClientSession()->GetRemoteIP()));
getUniquePlayerLock.unlock();
}
Party::KickMember(){
getUniquePlayerLock.lock();
ipList.erase(s2ws(kickedplayer->GetClientSession()->GetRemoteIP()));
getUniquePlayerLock.unlock();
}
Party::GetUniquePlayers(){
std::set<std::wstring>::iterator it;
std::wstring curIP;
std::list<CPlayer*> uniquePlayers;
if (!ipList.empty()) {
for (it = ipList.begin(); it != ipList.end(); it++)
{
curIP = *it;
//std::wcout << "\nChecking IP " << curIP;
for (int i = 0; i < m_byMemberInfoCount; i++)
{
//std::cout << "\n" << i;
CPlayer* player = GetPlayer(i);
if (player) {
if (curIP == s2ws(player->GetClientSession()->GetRemoteIP())) {
uniquePlayers.push_back(player);
//std::wcout << "\n" << curIP;
break;
}
}
}
}
}
return uniquePlayers;
}
```
我在这里完全没有想法。它必须是某种未定义的行为、内存损坏或我遗漏的一些非常明显的东西。也许在某些情况下 ipList 会在调用派对析构函数之前被销毁?我仍然不清楚头文件中声明的变量何时被视为“超出范围”并因此被破坏。任何帮助表示赞赏。
编辑:按照这个逻辑,player->GetClientSession()->GetRemoteIP() 的值是否会被销毁,直到它被重新填充?
Edit2:我已根据要求进行了一些更改以检查客户端会话和 IP 中的空值。这一次,我在访问集合的下界时遇到访问冲突错误。
```
template <class _Keyty>
_Tree_find_result<_Nodeptr> _Find_lower_bound(const _Keyty& _keyval) const {
const auto _Scary = _Get_scary();
_Tree_find_result<_Nodeptr> _Result{{_Scary->_Myhead->_Parent,_Tree_child::_Right},_Scary->_Myhead}; **ACCESS VIOLATION ERROR IS HERE**
_Nodeptr _Trynode = _Result._Location._Parent;
while (!_Trynode->_Isnil) {`enter code here`
_Result._Location._Parent = _Trynode;
if (_DEBUG_LT_PRED(_Getcomp(),_Traits::_Kfn(_Trynode->_Myval),_keyval)) {
_Result._Location._Child = _Tree_child::_Right;
_Trynode = _Trynode->_Right;
} else {
_Result._Location._Child = _Tree_child::_Left;
_Result._Bound = _Trynode;
_Trynode = _Trynode->_Left;
}
}
return _Result;
}
```
我可能对这个集合做什么来导致这个内存访问错误?它是在类函数中访问的成员变量,在任何地方都没有调用带外析构函数。我完全迷失在这里。
编辑 3:为下面的全局互斥锁添加 ifdef:
globalVariables.h:
#pragma once
#ifndef playerLockDefined
#include <mutex>
#define playerLockDefined
extern std::mutex getUniquePlayerLock;
#endif // !1
globalVariables.cpp:
#include "stdafx.h"
#include "globalVariables.h"
std::mutex getUniquePlayerLock;
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)