mem leak from vector.resize ?

Started by
6 comments, last by MaulingMonkey 17 years, 11 months ago
i've made my own mem leak tracker, and it seems to be reporting that im loosing memory when i call vector.resize which causes an allocation. i've tried vector.clear and vector.resize(0) to see if it releases the memory, but it appears it doesnt :-/ im using the STL that comes with vc2005 btw so it could just be that implmentation?
Advertisement
If you use the standard allocator it might be doing pool allocation and not deallocate the memory until the program is closed.
so is it safe to ignore any STL memory leaks then? if it doesnt return the data its only a few hundred bytes at the moment i guess
Quote:Original post by supagu
so is it safe to ignore any STL memory leaks then? if it doesnt return the data its only a few hundred bytes at the moment i guess


You can most likely just ignore it Is it a vector of scalar types or non-scalar types? resize calls erase, but erase doesn't do anything about scalar types, but with non-scalar types it calls delete right away. (resize calls erase if new size is smaller than old size, erase calls _Destroy, _Destroy calls _DestroyRange which calls the allocator's deallocate function for non-scalar types). Looking at the implementation I can now see that the leak doesn't come from a pool allocator though.
Are you using STL vector with a class of your own? If so, check that, that class is not leaking any memory (i.e.: your d'tor is clearing everything it needs to), and that your not allocating and forgetting about anything in any of the other methods of the class. Hope this helps :-)
Steven ToveySPUify | Twitter
Quote:Original post by supagu
i've tried vector.clear and vector.resize(0) to see if it releases the memory, but it appears it doesnt :-/

im using the STL that comes with vc2005 btw so it could just be that implmentation?


All versions of the STL that I'm aware of have a std::vector that hoards memory for reuse, I'm 99.9% sure it's required by the standard.

If you really want to get rid of the memory before the std::vector is destroyed (forcing you to allocate once more when you start to use it, instead of reusing the allready allocated memory), use the swap() function on a temporary std::vector, which directly swaps the memory pools instead of copying it all over by hand.

const unsigned a_big_number = 1000000;std::vector< int > numbers;numbers.resize( a_big_number );//numbers.size() == a_big_number//numbers.capacity() >= a_big_numbernumbers.resize( 0 );//numbers.size() == 0//numbers.capacity() >= a_big_number (memory still held onto)//a scope for a temporary:{    std::vector< int > temp;    numbers.swap( temp );    //numbers.size() == 0    //numbers.capacity() == 0    //temp.capacity() >= a_big_number     //at the end of this scope, temp is destroyed, deallocating the original allocation.}//but numbers still exists


Note that the ensuing reallocation when numbers is added to again may slow your program, which is why std::vector has the hoarding feature, so I wouldn't suggest doing this unless you're trying to slim the memory requirements to fit in a certain amount (e.g. to avoid paging memory to disk).

If you get this kind of behavior with any other kind of container than std::vector, then as the others have allready brought up, the allocator used is probably hoarding the memory itself. Since hoard-for-reuse "leaks" occur often enough in libraries, many leak detectors have options for identifying and ignoring these false positives.

For best results, use memleakdetector.report() after any containers have been destroyed. This means they will have cleaned up after themselves, meaning only the false positives from a hoarding allocator will show.
Here's how you "shrink to fit" a vector:

vector<int> myvec;......vector<int>(myvec).swap(myvec); // shrink to fit


The fact that you need to copy the data out of the vector and into a smaller block is one of the reasons why the vector doesn't shrink automatically: most memory managers can't deal with the release of only part of an allocated block. It's always all or nothing.

Exercise for the reader: write a memory allocator that can deallocate partial blocks. Deallocated blocks should be merged when adjacent. Study the effect this has on memory fragmentation.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Fruny
vector<int>(myvec).swap(myvec); // shrink to fit


Now that Fruny has reminded me of how to avoid a named temporary variable:

vector< int >().swap( numbers );


Is the equivilant to the entire temporary block in the code I posted.

This topic is closed to new replies.

Advertisement