string vector leak?

hi there,
i was testing STL vectors and STL strings and I found something I don't quite understand...... this is my test program:

#include <vector>
#include <string>
#include <conio.h>

using namespace std;

int main(void) {
vector<string> v;

for(int i = 0; i <= 500000; i++) {
v.push_back("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
}

printf("vector loaded\n");
_getch();

v.clear();
printf("vector cleared\n");
_getch();

return 0;
}

as far as I understand I should get my memory back when I issue the clear() instruction. I've been monitoring my program with Process Explorer (www.sysinternals.com) and i see aprox. 40 MB of private bytes when the vector is fully loaded but for some reason the memory goes down only to aprox. 20 MB when i clear it.

i have tested the same program with gcc and i have't seen this behaviour, memory is freed as expected.....

any clues am I doing something wrong

thx








Answer this question

string vector leak?

  • rain0x01


    thanks for your explanation Frank,

    i've found that this works too if you want to shrink a vector and it's simpler than using a vector of pointers:

    vector<string>(v1).swap(v1);







  • Omar Naeem


    ok, i understand it now:
    http://www.gamedev.net/community/forums/topic.asp topic_id=391685



  • Webdav101

    khyron wrote:
    as far as I understand I should get my memory back when I issue the clear() instruction.

    Not necessarily.

    Try adding printf statements to show the value of v.capacity() before you load the vector, after you load the vector and after you clear the vector. You'll find that the capacity of the vector does not go down after you call clear. The size goes down but not the capacity.

    Now, add the following code immediately before your for loop


    printf("ready to start\n");
    _getch();
    v.reserve (699913);
    printf(
    "ready to load\n");
    _getch();

    Monitor your program and you will find that the memory used rises to the approximately 20MB as soon as you call reserve, even though you have not yet executed the for loop to put anything into the vector.

    The memory will be returned when v goes out of scope and the destructor is called. If you can't use scope and really want to get rid of that last 20MB after you call clear() the easiest way to do it would be to change v to be a pointer to vector<string> and call delete on v. For example...


    vector<string> * v1 = new vector<string>;
    printf(
    "ready to start\n");
    _getch();
    v1->reserve (699913);
    printf(
    "ready to clear\n");
    _getch();
    v1->clear();
    printf(
    "ready to delete\n");
    _getch();

    delete v1;
    printf(
    "deleted\n");
    _getch();

    You could also derive your own tidy-capable class from vector and use that instead so that you could call _Tidy() but I don't like playing games to get around the protected keyword.

    You should think about whether you really want to get rid of that memory though. You'll just have to allocate the memory again if you put another 500,000 items into the vector. My guess is that is why clear() doesn't deallocate the memory. It assumes the vector will grow to comparable size again (or that the vector will go out of scope and be deleted anyway).

    i have tested the same program with gcc and i have't seen this behaviour, memory is freed as expected.....

    One of the joys of the STL is that it is distributed in source form so you can read the code to see how vector::clear() is implemented. Open the file 'vector' in Visual Studio's include folder and you can see how clear() is implemented there. Open the same file in gcc's include folder and you can see how the gcc version is implemented.


  • string vector leak?