Removed circular shared_ptr reference between IRCMember and IRCChannel (mem leak)

master
Tomatix 5 years ago
parent 58cc43218c
commit 2adf7a2f86
  1. 21
      IRCClient/IRCBase.cpp
  2. 18
      IRCClient/IRCMember.cpp
  3. 8
      IRCClient/IRCMember.h

@ -360,8 +360,8 @@ struct IRCBasePriv
else if (prefix.nickname() == nickname) else if (prefix.nickname() == nickname)
channels.erase( channels.erase(
std::find_if(channels.begin(), channels.end(), std::find_if(channels.begin(), channels.end(),
[&channel](std::shared_ptr<IRCChannel> cptr) { [&channel](std::weak_ptr<IRCChannel> cptr) {
return channel == cptr->name(); return channel == cptr.lock()->name();
} }
)); ));
} }
@ -1030,8 +1030,8 @@ void IRCBasePriv::parseIncoming(const std::string& line)
std::vector<std::string> channelsAffected; std::vector<std::string> channelsAffected;
auto member = super.getMember(sender.nickname()); auto member = super.getMember(sender.nickname());
const auto& chans = member->channels(); const auto& chans = member->channels();
for (auto c : chans) for (const auto& c : chans)
channelsAffected.push_back(c->name()); channelsAffected.push_back(c.lock()->name());
member->setNickname(msg); member->setNickname(msg);
super.onMsgNick(sender, msg, channelsAffected); super.onMsgNick(sender, msg, channelsAffected);
@ -1084,9 +1084,9 @@ void IRCBasePriv::parseIncoming(const std::string& line)
auto member = super.getMember(sender.nickname()); auto member = super.getMember(sender.nickname());
if (member) { if (member) {
const auto& chans = member->channels(); const auto& chans = member->channels();
for (auto c : chans) { for (const auto& c : chans) {
channelsAffected.push_back(c); channelsAffected.push_back(c.lock());
channelsAffectedStr.push_back(c->name()); channelsAffectedStr.push_back(c.lock()->name());
} }
auto it = std::find(allMembers.begin(), allMembers.end(), member); auto it = std::find(allMembers.begin(), allMembers.end(), member);
@ -1277,9 +1277,10 @@ void IRCBasePriv::parseIncoming(const std::string& line)
auto member = super.getMember(sender.nickname()); auto member = super.getMember(sender.nickname());
if (member) { if (member) {
const auto& chans = member->channels(); const auto& chans = member->channels();
for (auto c : chans) { for (const auto& c : chans) {
channelsAffected.push_back(c->name()); const auto cptr = c.lock();
c->delMember(member); channelsAffected.push_back(cptr->name());
cptr->delMember(member);
} }
} }
super.v3onMsgAway(sender, msg, channelsAffected); super.v3onMsgAway(sender, msg, channelsAffected);

@ -19,21 +19,29 @@ void IRCMember::setPrefix(const IRCPrefix& prefix)
m_prefix = prefix; m_prefix = prefix;
} }
const std::vector<std::shared_ptr<IRCChannel>>& IRCMember::channels() const std::vector<std::weak_ptr<IRCChannel>>& IRCMember::channels()
{ {
return m_channels; return m_channels;
} }
void IRCMember::addChannel(std::shared_ptr<IRCChannel> channel) void IRCMember::addChannel(std::weak_ptr<IRCChannel> channel)
{ {
auto it = std::find(m_channels.begin(), m_channels.end(), channel); auto it = std::find_if(m_channels.begin(), m_channels.end(),
[channel](const std::weak_ptr<IRCChannel>& p){
return p.lock() == channel.lock();
});
if (it == m_channels.end()) if (it == m_channels.end())
m_channels.emplace_back(channel); m_channels.emplace_back(channel);
} }
void IRCMember::delChannel(std::shared_ptr<IRCChannel> channel) void IRCMember::delChannel(std::weak_ptr<IRCChannel> channel)
{ {
auto newEnd = std::remove(m_channels.begin(), m_channels.end(), channel); auto newEnd = std::remove_if(m_channels.begin(), m_channels.end(),
[channel](const std::weak_ptr<IRCChannel>& p){
return p.lock() == channel.lock();
});
m_channels.erase(newEnd, m_channels.end()); m_channels.erase(newEnd, m_channels.end());
} }

@ -16,15 +16,15 @@ public:
const IRCPrefix& prefix() const; const IRCPrefix& prefix() const;
void setPrefix(const IRCPrefix& prefix); void setPrefix(const IRCPrefix& prefix);
const std::vector<std::shared_ptr<IRCChannel>>& channels(); const std::vector<std::weak_ptr<IRCChannel>>& channels();
void addChannel(std::shared_ptr<IRCChannel> channel); void addChannel(std::weak_ptr<IRCChannel> channel);
void delChannel(std::shared_ptr<IRCChannel> channel); void delChannel(std::weak_ptr<IRCChannel> channel);
void setNickname(const std::string& nickname); void setNickname(const std::string& nickname);
private: private:
IRCPrefix m_prefix; IRCPrefix m_prefix;
std::vector<std::shared_ptr<IRCChannel>> m_channels; std::vector<std::weak_ptr<IRCChannel>> m_channels;
}; };
#endif // IRCMEMBER_H #endif // IRCMEMBER_H

Loading…
Cancel
Save