Opened 5 years ago

Closed 5 years ago

#13500 closed Bugs (fixed)

Memory leak when using erase on string vectors

Reported by: anonymous Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: container
Version: Boost 1.58.0 Severity: Problem
Keywords: Cc:

Description

Consider the following example:

#include <boost/container/vector.hpp>
#include <boost/container/string.hpp>

int main() {
  boost::container::vector<boost::container::string> myVec;
  
//  myVec.push_back("Short string");
  myVec.push_back("This is a long string that exceeds a certain threshold (23 in my case)");
  myVec.erase(myVec.begin());
  
  return 0;
}

When running this example and pushing back the long string, valgrind reports a memory leak (see attached file). When using the short string, there is no leak. I assume this has to do with the boost short string optimization, which puts shorter strings into a buffer living in stack instead of allocating a buffer on the heap.

Also, when I do not erase(..) the element but let the vector destructor clean up the memory, there is no leak.

Looking at the implementation of vector's erase(..):

   //! <b>Effects</b>: Erases the element at position pos.
   //!
   //! <b>Throws</b>: Nothing.
   //!
   //! <b>Complexity</b>: Linear to the elements between pos and the
   //!   last element. Constant if pos is the last element.
   iterator erase(const_iterator position)
   {
      BOOST_ASSERT(this->priv_in_range(position));
      const pointer p = vector_iterator_get_ptr(position);
      T *const pos_ptr = boost::movelib::to_raw_pointer(p);
      T *const beg_ptr = this->priv_raw_begin();
      T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr);
      //Move elements forward and destroy last
      this->priv_destroy_last(pos_ptr == new_end_ptr);
      return iterator(p);
}

I think the condition passed as argument to priv_destroy_last(const bool moved) has to be negated? pos_ptr == new_end_ptr is fulfilled if ::boost::container::move has NOT moved anything.

Attachments (1)

boost_leak_valgrind.txt (2.7 KB ) - added by pleemann@… 5 years ago.
valgrind output

Download all attachments as: .zip

Change History (3)

by pleemann@…, 5 years ago

Attachment: boost_leak_valgrind.txt added

valgrind output

comment:1 by Ion Gaztañaga, 5 years ago

Many thanks for the report and the explanations. Fixed in:

https://github.com/boostorg/container/commit/b3eee90a81ce935918ae1c3c764ae166a8d347df

comment:2 by Ion Gaztañaga, 5 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.