C++ std::set<std::wstring> 奇怪的行为?

问题描述

我正在为游戏编写派对系统,我从包含派对 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 (将#修改为@)