User オブジェクトのリストを値として格納する 2 つのマップがあります。これらの値のキーは、以下に定義されている uint32_t および SocketAddress 構造体です。
最初のマップでは問題なく値が挿入されますが、デバッグ中にローカルを確認すると、2 番目のマップでは値がまったく挿入されていないように見えます。関連するコードは次のとおりです。
ソケットアドレス:
struct SocketAddress {
sockaddr from;
socklen_t fromlen;
SocketAddress& operator=(const SocketAddress &source);
bool operator==(const SocketAddress &source) const;
bool operator!=(const SocketAddress &source) const;
bool operator<(const SocketAddress &source) const;
bool operator>(const SocketAddress &source) const;
bool operator<=(const SocketAddress &source) const;
bool operator>=(const SocketAddress &source) const;
};
Socket::SocketAddress& Socket::SocketAddress::operator=(const SocketAddress &source) {
memcpy(&from, &source.from, source.fromlen);
fromlen = source.fromlen;
return *this;
}
bool Socket::SocketAddress::operator==(const SocketAddress &source) const {
return (fromlen == source.fromlen && memcmp(&from, &source.from, fromlen) == 0);
}
bool Socket::SocketAddress::operator!=(const SocketAddress &source) const {
return !this->operator==(source);
}
bool Socket::SocketAddress::operator<(const SocketAddress &source) const {
return (fromlen < source.fromlen || memcmp(&from, &source.from, fromlen) < 0);
}
bool Socket::SocketAddress::operator>(const SocketAddress &source) const {
return (fromlen > source.fromlen || memcmp(&from, &source.from, source.fromlen) > 0);
}
bool Socket::SocketAddress::operator<=(const SocketAddress &source) const {
return !this->operator>(source);
}
bool Socket::SocketAddress::operator>=(const SocketAddress &source) const {
return !this->operator<(source);
}
ユーザー コンストラクターと関連する変数:
std::map<uint32_t, std::shared_ptr<User>> User::_usersListBySession;
std::map<Socket::SocketAddress, std::shared_ptr<User>> User::_userListByAddress;
std::atomic<unsigned int> User::_nextSessionID = 0;
User::User(const Socket::SocketAddress& addr) {
address = addr;
sessionID = ++_nextSessionID;
// This seems to work just fine
_usersListBySession.insert(std::pair<uint32_t, std::shared_ptr<User>>(sessionID, std::shared_ptr<User>(this)));
// This does not
_userListByAddress.insert(std::pair<Socket::SocketAddress, std::shared_ptr<User>>(addr, std::shared_ptr<User>(this)));
}
住所の定義:
const Socket::SocketAddress& address
意図したとおりに動作しないコードのセグメント。
std::shared_ptr<User> user = User::getUserWithAddress(address);
if (!user) {
user = std::shared_ptr<User>(new User(address));
}
マップ検索機能:
std::shared_ptr<User> User::getUserWithAddress(const Socket::SocketAddress& addr) {
return _userListByAddress[addr];
}
std::shared_ptr<User> User::getUserWithSessionID(uint32_t sessionid) {
return _usersListBySession[sessionid];
}
User::getUserWithAddress(address) を呼び出すと、返されたユーザーにユーザーがいません! メモリ内のペアを見ると、アドレスがキーとして格納されているように見えますが、ユーザーへのポインタは格納されていません。私は何を考えるべきかわからない!誰にもアイデアはありますか?
編集:以下のユーザーによって特定されたいくつかの問題があったようですが、それが私の問題の原因ではないようです.
演算子を修正した後、問題を次の行に切り分けました。
assert(this->address == addr);
_userListByAddress.insert(std::pair<Socket::SocketAddress, std::shared_ptr<User>>(addr, std::shared_ptr<User>(this)));
assert(this->address == addr);
最初のアサーションは成功し、2 番目のアサーションは失敗します。
編集#2:
これを行うことで問題を解決したようです:
std::shared_ptr<User> user(this);
_usersListBySession.insert(std::pair<uint32_t, std::shared_ptr<User>>(sessionID, user));
assert(this->address == addr); // works
_userListByAddress.insert(std::pair<Socket::SocketAddress, std::shared_ptr<User>>(addr, user));
assert(this->address == addr); // works
理由がわかりません。別の質問の仕事のように聞こえます。