Try again to fix memory leak reported by Scott.

This time, use a shared_ptr.
This commit is contained in:
Richard Kimberly Heck 2020-02-23 16:39:00 -05:00
parent 72c581ebdb
commit 0daceae649
2 changed files with 15 additions and 12 deletions

View File

@ -154,7 +154,8 @@ typedef vector<LabelInfo> LabelCache;
typedef map<docstring, Buffer::References> RefCache; typedef map<docstring, Buffer::References> RefCache;
// A storehouse for the cloned buffers. // A storehouse for the cloned buffers.
std::list<CloneList *> cloned_buffers; typedef list<CloneList_ptr> CloneStore;
CloneStore cloned_buffers;
} // namespace } // namespace
@ -371,7 +372,7 @@ public:
/// This one is useful for preview detached in a thread. /// This one is useful for preview detached in a thread.
Buffer const * cloned_buffer_; Buffer const * cloned_buffer_;
/// ///
CloneList * clone_list_; CloneList_ptr clone_list_;
/// are we in the process of exporting this buffer? /// are we in the process of exporting this buffer?
mutable bool doing_export; mutable bool doing_export;
@ -530,8 +531,8 @@ Buffer::~Buffer()
// loop over children // loop over children
for (auto const & p : d->children_positions) { for (auto const & p : d->children_positions) {
Buffer * child = const_cast<Buffer *>(p.first); Buffer * child = const_cast<Buffer *>(p.first);
if (d->clone_list_->erase(child)) if (d->clone_list_->erase(child))
delete child; delete child;
} }
// if we're the master buffer, then we should get rid of the list // if we're the master buffer, then we should get rid of the list
// of clones // of clones
@ -540,14 +541,15 @@ Buffer::~Buffer()
// children still has a reference to this list. But we will try to // children still has a reference to this list. But we will try to
// continue, rather than shut down. // continue, rather than shut down.
LATTEST(d->clone_list_->empty()); LATTEST(d->clone_list_->empty());
list<CloneList *>::iterator it = // The clone list itself is empty, but it's still referenced in our list
// of clones. So let's find it and remove it.
CloneStore::iterator it =
find(cloned_buffers.begin(), cloned_buffers.end(), d->clone_list_); find(cloned_buffers.begin(), cloned_buffers.end(), d->clone_list_);
if (it == cloned_buffers.end()) { if (it == cloned_buffers.end()) {
// We will leak in this case, but it is safe to continue. // We will leak in this case, but it is safe to continue.
LATTEST(false); LATTEST(false);
} else } else
cloned_buffers.erase(it); cloned_buffers.erase(it);
delete d->clone_list_;
} }
// FIXME Do we really need to do this right before we delete d? // FIXME Do we really need to do this right before we delete d?
// clear references to children in macro tables // clear references to children in macro tables
@ -594,8 +596,8 @@ Buffer::~Buffer()
Buffer * Buffer::cloneWithChildren() const Buffer * Buffer::cloneWithChildren() const
{ {
BufferMap bufmap; BufferMap bufmap;
cloned_buffers.push_back(new CloneList); cloned_buffers.push_back(CloneList_ptr(new CloneList));
CloneList * clones = cloned_buffers.back(); CloneList_ptr clones = cloned_buffers.back();
cloneWithChildren(bufmap, clones); cloneWithChildren(bufmap, clones);
@ -608,7 +610,7 @@ Buffer * Buffer::cloneWithChildren() const
} }
void Buffer::cloneWithChildren(BufferMap & bufmap, CloneList * clones) const void Buffer::cloneWithChildren(BufferMap & bufmap, CloneList_ptr clones) const
{ {
// have we already been cloned? // have we already been cloned?
if (bufmap.find(this) != bufmap.end()) if (bufmap.find(this) != bufmap.end())
@ -658,8 +660,8 @@ void Buffer::cloneWithChildren(BufferMap & bufmap, CloneList * clones) const
Buffer * Buffer::cloneBufferOnly() const { Buffer * Buffer::cloneBufferOnly() const {
cloned_buffers.push_back(new CloneList); cloned_buffers.push_back(CloneList_ptr(new CloneList));
CloneList * clones = cloned_buffers.back(); CloneList_ptr clones = cloned_buffers.back();
Buffer * buffer_clone = new Buffer(fileName().absFileName(), false, this); Buffer * buffer_clone = new Buffer(fileName().absFileName(), false, this);
// The clone needs its own DocumentClass, since running updateBuffer() will // The clone needs its own DocumentClass, since running updateBuffer() will

View File

@ -82,6 +82,7 @@ class Buffer;
typedef std::list<Buffer *> ListOfBuffers; typedef std::list<Buffer *> ListOfBuffers;
/// a list of Buffers we cloned /// a list of Buffers we cloned
typedef std::set<Buffer *> CloneList; typedef std::set<Buffer *> CloneList;
typedef std::shared_ptr<CloneList> CloneList_ptr;
/** The buffer object. /** The buffer object.
@ -231,7 +232,7 @@ private:
/// ///
typedef std::map<Buffer const *, Buffer *> BufferMap; typedef std::map<Buffer const *, Buffer *> BufferMap;
/// ///
void cloneWithChildren(BufferMap &, CloneList *) const; void cloneWithChildren(BufferMap &, CloneList_ptr) const;
/// save checksum of the given file. /// save checksum of the given file.
void saveCheckSum() const; void saveCheckSum() const;
/// read a new file /// read a new file