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

@ -19,21 +19,29 @@ void IRCMember::setPrefix(const IRCPrefix& 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;
}
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())
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());
}

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

Loading…
Cancel
Save