Subject: [Boost-bugs] [Boost C++ Libraries] #13500: Memory leak when using erase on string vectors
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2018-03-29 11:25:03
#13500: Memory leak when using erase on string vectors
------------------------------+---------------------------
Reporter: anonymous | Owner: Ion Gaztañaga
Type: Bugs | Status: new
Milestone: To Be Determined | Component: container
Version: Boost 1.58.0 | Severity: Problem
Keywords: |
------------------------------+---------------------------
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.
-- Ticket URL: <https://svn.boost.org/trac10/ticket/13500> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2018-03-29 11:30:42 UTC