Modify

Ticket #2908 (closed Bugs: fixed)

Opened 5 years ago

Last modified 5 years ago

unordered_map has no destructor!

Reported by: anonymous Owned by: danieljames
Milestone: Boost 1.39.0 Component: unordered
Version: Boost 1.37.0 Severity: Problem
Keywords: unordered_map,destructor Cc:

Description

I noticed that the unordered_map has no destructor as one would assume. There should be a destructor that calls clear() so that the content of the map is deleted. (cf. RAII -  http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)

I ran into a serious memory leak because of that, when using an unordered_map locally and assuming that it clears its content when being destroyed.

Attachments

Change History

comment:1 Changed 5 years ago by danieljames

  • Status changed from new to closed
  • Resolution set to invalid

The memory management is taken care of by an internal implementation class called hash_table_data_equivalent_keys or hash_table_data_unique_keys. You can see the destructor here:

 https://svn.boost.org/trac/boost/browser/trunk/boost/unordered/detail/hash_table_impl.hpp?rev=51995#L380

The destructor is called BOOST_UNORDERED_TABLE_DATA because I'm using macros to define the two different hash tables with a single implementation.

unordered_map and unordered_set's implicit destructors both call the implementation classes' destructors, so there's no need to define a destructor for those classes.

comment:2 Changed 5 years ago by anonymous

But somehow the unordered_map was only cleared if and only if I called clear() manually. I can post you some details if you like.

comment:3 Changed 5 years ago by danieljames

If you send me an example, I'll have a look at it. Let me know which compiler you're using and on which platform.

comment:4 Changed 5 years ago by anonymous

  • Version changed from Boost 1.38.0 to Boost 1.37.0

Here is the example (I tried to skip the unnecessary stuff):

definitions:

typedef boost::tuple<TPoint, TPoint, TPoint> TEdgeIdentifier; typedef std::pair<PTempPlzEdge, unsigned> TCountedEdge;

typedef boost::unordered_map<TEdgeIdentifier, TCountedEdge, TEdgeIdentifierHash, TEdgeIdentifierEqual> TEdgeCountMap;

method:


TEdgeCountMap EdgeCountDifferentMap?( 1.5 * List.size() ); for( "it in List" ){

TEdgeCountMap::iterator found = EdgeCountDifferentMap?.find( (*it)->GetEdgeIdentifier?() );

if( found != EdgeCountDifferentMap?.end() ){

if( "some condition" ){

found->second.second ++;

}

}else{

EdgeCountDifferentMap?.insert( std::make_pair( (*it)->GetEdgeIdentifier?(), std::make_pair( *it , 1 ) ) );

}

}

for( "it in List" ){

TEdgeCountMap::iterator found = EdgeCountDifferentMap?.find( (*it)->GetEdgeIdentifier?() );

if( found != EdgeCountDifferentMap?.end() && found->second.second > 1 ){

continue;

}

"do something with *it"

}

EdgeCountDifferentMap?.clear(); if this is uncommented, I have a huge memory leak although this is the end of the method and EdgeCountDifferentMap? should be destroyed

Additionally I noticed (using AQtime 6) that the memory that is allocated within the constructor call "TEdgeCountMap EdgeCountDifferentMap?( 1.5 * List.size() );" is not freed too.

I am in the unfortunate situation that I have to use Borland C++ Builder 4. I use boost version 1.37.

comment:5 Changed 5 years ago by anonymous

  • Status changed from closed to reopened
  • Resolution invalid deleted

comment:6 Changed 5 years ago by danieljames

(In [53253]) Add explicit destructors to the unordered containers. Refs #2908.

Isn't really needed but it doesn't hurt.

comment:7 Changed 5 years ago by anonymous

  • Status changed from reopened to closed
  • Resolution set to fixed

Well, guess what? That worked! Strange, as I can comprehend your previous reasoning totaly. Seems like the old Borland C++-Compiler has a serious issue there. :(

comment:8 Changed 5 years ago by danieljames

(In [53465]) Merge latest changes for unordered. Improved compatability and a few tweaks.

Merged revisions 53127,53253,53256,53311,53314,53316-53318 via svnmerge from  https://svn.boost.org/svn/boost/trunk

........

r53127 | danieljames | 2009-05-20 07:43:38 +0100 (Wed, 20 May 2009) | 1 line

Better configuration for boost.unordered.

........

r53253 | danieljames | 2009-05-25 20:14:07 +0100 (Mon, 25 May 2009) | 3 lines

Add explicit destructors to the unordered containers. Refs #2908.

Isn't really needed but it doesn't hurt.

........

r53256 | danieljames | 2009-05-25 20:45:23 +0100 (Mon, 25 May 2009) | 1 line

Unordered change log for explicit destructors.

........

r53311 | danieljames | 2009-05-27 18:42:01 +0100 (Wed, 27 May 2009) | 1 line

Missing changelog entry.

........

r53314 | danieljames | 2009-05-27 18:44:09 +0100 (Wed, 27 May 2009) | 1 line

Use lightweight_test for unordered.

........

r53316 | danieljames | 2009-05-27 19:19:32 +0100 (Wed, 27 May 2009) | 1 line

Some workarounds for old versions of Borland.

........

r53317 | danieljames | 2009-05-27 19:32:22 +0100 (Wed, 27 May 2009) | 1 line

Fix a change accidentally included in the last commit.

........

r53318 | danieljames | 2009-05-27 19:32:38 +0100 (Wed, 27 May 2009) | 1 line

Remove an unused function.

........

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.