82107

STL container leak

Question:

I'm using a vector container to hold instances of an object which contain 3 ints and 2 std::strings, this is created on the stack and populated from a function in another class but running the app through deleaker shows that the std::strings from the object are all leaked. Here's the code:

// Populator function: void PopulatorClass::populate(std::vector<MyClass>& list) { // m_MainList contains a list of pointers to the master objects for( std::vector<MyClass*>::iterator it = m_MainList.begin(); it != m_MainList.end(); it++ ) { list.push_back(**it); } } // Class definition class MyClass { private: std::string m_Name; std::string m_Description; int m_nType; int m_nCategory; int m_nSubCategory; }; // Code causing the problem: std::vector<MyClass> list; PopulatorClass.populate(list);

When this is run through deleaker the leaked memory is in the allocator for the std::string classes.

I'm using Visual Studio 2010 (CRT).

Is there anything special I need to do to make the strings delete properly when unwinding the stack and deleting the vector?

Thanks, J

Answer1:

<strong>Every time you got a problem with the STL implementation doing something strange or wrong like a memory leak, try this</strong> :

<ul><li><strong>Reproduce the most basic example of what you try to achieve.</strong> If it runs without a leak, then the problem is in the way you fill the data. <strong>It's the most probable source of problem (I mean your own code).</strong></li> </ul>

Not tested simple on-the-fly example for your specific problem :

#include <string> #include <sstream> // Class definition struct MyClass { // struct for convenience std::string m_Name; std::string m_Description; int m_nType; int m_nCategory; int m_nSubCategory; }; // Prototype of populator function: void populate(std::vector<MyClass>& list) { const int MAX_TYPE_IDX = 4; const int MAX_CATEGORY_IDX = 8; const int MAX_SUB_CATEGORY_IDX = 6; for( int type_idx = 0; type_idx < MAX_TYPE_IDX ; ++type_idx) for( int category_idx = 0; category_idx < MAX_CATEGORY_IDX ; ++category_idx) for( int sub_category_idx = 0; sub_category_idx < MAX_SUB_CATEGORY_IDX ; ++sub_category_idx) { std::stringstream name_stream; name_stream << "object_" << type_idx << "_" << category_idx << "_" << sub_category_idx ; std::stringstream desc_stream; desc_stream << "This is an object of the type N°" << type_idx << ".\n"; desc_stream << "It is of category N°" << category_idx << ",\n"; desc_stream << "and of sub-category N°" << category_idx << "!\n"; MyClass object; object.m_Name = name_stream.str(); object.m_Description = desc_stream.str(); object.m_nType = type_idx; m_nCategory = m_nSubCategory = list.push_back( object ); } } int main() { // Code causing the problem: std::vector<MyClass> list; populate(list); // memory leak check? return 0; } <ul><li>If you still got the memory leak, <strong>first check that it's not a false-positive from your leak detection software</strong>. </li> <li>Then if it's not, <strong>google for memory leak problems with your STL implementation</strong> (most of the time on the compiler developer website). The implementor might provide a bug tracking tool where you could search in for the same problem and potential solution.</li> <li>If you still can't find the source of the leak, maybe <strong>try to build your project with a different compiler (if you can)</strong> and see if it have the same effect. Again if the leak still occurs, the problem have a lot of chances to come from your code.</li> </ul>

Answer2:

May be <a href="http://connect.microsoft.com/VisualStudio/feedback/details/596565/memory-leak-with-std-vector-std-string-insert-using-const-std-string#details" rel="nofollow">Memory leak with std::vector<std::string></a> or something like this.

Answer3:

Probably same root issue as Alexey's link. The shipped version has broken move code for basic_string. MS abandoned us VC10 users, so you must fix it yourself. in xstring file you have this:

_Myt& assign(_Myt&& _Right) { // assign by moving _Right if (this == &_Right) ; else if (get_allocator() != _Right.get_allocator() && this->_BUF_SIZE <= _Right._Myres) *this = _Right; else { // not same, clear this and steal from _Right _Tidy(true); if (_Right._Myres < this->_BUF_SIZE) _Traits::move(this->_Bx._Buf, _Right._Bx._Buf, _Right._Mysize + 1); else { // copy pointer this->_Bx._Ptr = _Right._Bx._Ptr; _Right._Bx._Ptr = 0; } this->_Mysize = _Right._Mysize; this->_Myres = _Right._Myres; _Right._Mysize = 0; _Right._Myres = 0; } return (*this); }

Note the last

_Right._Myres = 0;

that should happen only under the last condition, for the short case _Right should better be left alone.

As the capacity is set to 0 instead of 15, other code will take unintended branch in function Grow() when you assign another small string and will allocate a block of memory just to trample over the pointer with the immediate string content.

Recommend

  • Apache CXF Webservice failing on AJAX call
  • Odd form closing behavior when using taskbar's Close All Windows
  • Cyclomatic complexity using jar files
  • Avoid throwing expectation_failure when expectation parser fails
  • Send data from service to activity and screen rotation
  • How can I suppress the prompt to “Unify Duplicated Vertices” when opening several meshes from regula
  • Best way to initialise / clear a string variable cocoa
  • C++ Container performance question
  • Get all stl vector elements greater than a value
  • How to correctly append dynamic GetUIKit accordions?
  • Generate a business key
  • IF statement formatting best-practise, what's your style?
  • c++ search a vector for element first seen position
  • JSF2.0 + Primefaces 3.0.1 + jquery 1.6.4 + p:commandLink + IE8 throws Unexpected call to method or p
  • Reassigning an array frees the memory used by it?
  • Lua: Line breaks in strings
  • Are there any side effects from calling SQLAlchemy flush() within code?
  • Wrong labels when plotting a time series pandas dataframe with matplotlib
  • abstracting over a collection
  • User messaging system
  • Can't remove headers after they are sent
  • Is there a way to save the selected text and highlight it again once the page is refreshed?
  • ASP.NET MVC Application won't update some controllers
  • C++ pointer value changes with static_cast
  • WPF ICommand CanExecute(): RaiseCanExecuteChanged() or automatic handling via DispatchTimer?
  • D3 nodes and links from JSON with nested arrays of children
  • Meteor: Do Something On Email Verification Confirmation
  • Adding a button at the bottom of a table view
  • Getting last autonumber in access
  • Does CUDA 5 support STL or THRUST inside the device code?
  • Where to put my custom functions in Wordpress?
  • Delete MySQLi record without showing the id in the URL
  • GridView Sorting works once only
  • RestKit - RKRequestDelegate does not exist
  • How to format a variable of double type
  • WPF Applying a trigger on binding failure
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • How can I remove ASP.NET Designer.cs files?
  • Are Kotlin's Float, Int etc optimised to built-in types in the JVM? [duplicate]
  • Programmatically clearing map cache