multimap.clear() does not free its memory

Brian Budge brian.budge@gmail.com
Fri Apr 8 11:44:00 GMT 2005


Hi Toon -

The default allocator for the standard library (STL) stuff is
implementation dependent.  That means it won't necessarily use the
same memory pool as operator new.  Moreover, even within any given
pool, depending on the implementation, the implementor might decide to
allocate memory for different scenarios.

You'd probably have reasonable luck
allocating/deleting/allocating/deleting with operator new and/or the
stl's allocator, but not necessarily when you mix the two.

  Brian

On Apr 8, 2005 11:54 AM, Toon Knapen <toon.knapen@fft.be> wrote:
> Eljay Love-Jensen wrote:
> 
> > So when you say "multimap.clear() does not free its memory" (in Linux), the mistake
> > you are making is assuming that the process space is consumed space.
> > That's assumption is not true.
> 
> OK I've done some more reading on the linux mem subsystem but there's
> still something weird: The memory that stored the multimap is not reused
> when doing more allocations! (so currently I do not care anymore if the
> 'memory is given back to the OS', I care about the virtual-page-frame's
> being reused)
> 
> In my test-program for instance (see below), I create a multimap, fill
> it up and delete it again. After the delete, the memory that was used to
> store the data in the multimap is still in the process' free mem pool.
> This is great because apparantly when I create now a new multimap (of
> the same size) it reuses these pages. After deleting this second
> multimap the memory used to store the data again remains in the process'
> free mem pool. But surprisingly if I now allocate one char on the heap,
> my heap consumption rises (and thus the char is not stored re-using the
> memory that was used to store the multimap and that is now in the
> process' free mem pool)(see the proof in the output from the
> test-program that is at the end of this mail).
> 
> Another interesting thing (that I do not understand) is that if I
> allocate a bunch of characters (and also write to the addresses to force
> the page-table to point to a physical page) and delete them afterwards,
> the memory consumption goes back to its original value. So is this
> memory not going to the process' memory pool ?
> 
> 
> > Interestingly, this topic just came up recently, on 2005.Mar.22
> > ("Problem with delete[] in class destructor") as well.
> > You can check the forum archives for details.
> >
> 
> Sorry I missed that (but I was on vacation at the time and it's so hard
> to keep up when on vacation).
> 
> Program below:
> 
> #include <malloc.h>
> #include <map>
> #include <iostream>
> 
> void report_mem()
> {
>    static struct mallinfo l_mallinfo ;
>    l_mallinfo = mallinfo();
>    std::cout << "mem: " <<  l_mallinfo.uordblks + l_mallinfo.hblkhd <<
> std::endl ;
> }
> 
> int main()
> {
>    std::cout << "\nHeap consumption when starting up" << std::endl ;
>    report_mem() ;
> 
>    { // bunch of char's
>      const int size = 1000000 ;
>      char* p[ size ] ;
>      for(int i = 0 ; i < size ; ++i ) { p[i] = new char ; *p[i] = 'a' ; }
>      std::cout << "\nJust allocated bunch of char's" << std::endl ;
>      report_mem() ;
>      for(int i = 0 ; i < size ; ++i ) delete p[i] ;
>      std::cout << "\nJust de-allocated bunch of char's" << std::endl ;
>      report_mem() ;
>    }
> 
>    { // bunch of pair's
>      const int size = 100000 ;
>      std::pair<int,int>* p[ size ] ;
>      for(int i = 0 ; i < size ; ++i ) p[i] = new std::pair<int,int>(3,4) ;
>      std::cout << "\nJust allocated bunch of pair's" << std::endl ;
>      report_mem() ;
>      for(int i = 0 ; i < size ; ++i ) delete p[i] ;
>      std::cout << "\nJust de-allocated bunch of pair's" << std::endl ;
>      report_mem() ;
>    }
>    { // multimap
>      std::multimap< int, int > map ;
> 
>      for(int i = 0 ; i < 100000 ; ++i ) {
>        map.insert( std::pair< int, int >( 0, 0 ) ) ;
>      }
> 
>      std::cout << "\nfirst map is filled" << std::endl ;
>      report_mem() ;
> 
>      map.clear() ;
> 
>      std::cout << "\nfirst map is cleared" << std::endl ;
>      report_mem() ;
>    }
> 
>    {
>      std::multimap< int, int > map ;
> 
>      for(int i = 0 ; i < 100000 ; ++i ) {
>        map.insert( std::pair< int, int >( 0, 0 ) ) ;
>      }
> 
>      std::cout << "\nsecond map is filled" << std::endl ;
>      report_mem() ;
> 
>      map.clear() ;
> 
>      std::cout << "\nsecond map is cleared" << std::endl ;
>      report_mem() ;
>    }
> 
>    std::cout << "\nAll maps should be destroyed" << std::endl ;
>    report_mem() ;
> 
>    new char ;
>    std::cout << "\nAllocated one more character" << std::endl ;
>    report_mem() ;
> 
>    return 0 ;
> }
> 
> Output on my machine:
> 
> Heap consumption when starting up
> mem: 0
> 
> Just allocated bunch of char's
> mem: 16000000
> 
> Just de-allocated bunch of char's
> mem: 0
> 
> Just allocated bunch of pair's
> mem: 1600000
> 
> Just de-allocated bunch of pair's
> mem: 0
> 
> first map is filled
> mem: 2492704
> 
> first map is cleared
> mem: 2492704
> 
> second map is filled
> mem: 2492704
> 
> second map is cleared
> mem: 2492704
> 
> All maps should be destroyed
> mem: 2492704
> 
> Allocated one more character
> mem: 2492720
> 
>



More information about the Gcc-help mailing list