std::vector cleanup problem? (c++, not irrlicht related)

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

std::vector cleanup problem? (c++, not irrlicht related)

Post by freetimecoder »

Hi,

I have a problem and I have been trying to solve it for quite a while :(
I use a simple std::vector to store pointers to objects. But when I want to delete the objects I have to much ram usage left over.

When I start the programm it uses 328 K ram. When the objects are created it uses 2.448 K and when I delete everything I have 1.128 K left over with method 1 and 1.108 K left with method 2.

I have researched about how to delete a vector and the methods should work :/ This is the code stripped down to the problem:

Code: Select all

#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;

class someTestClass
{
private:
    double someData;
public:
    someTestClass()
    {
        someData = rand()/2.0;
    }
    ~someTestClass()
    {
    }
};

int main()
{
    vector<someTestClass*> vector_data;

    cout<<"creating\n";
    while(vector_data.size()<100000)
    {
        someTestClass *temp = new someTestClass();
        vector_data.push_back(temp);
    }


    cout<<"deleting\n";

    //Of course both methods do not work together, so comment or uncomment them
    ///Method 1
    vector<someTestClass*>::iterator it_knoten = vector_data.begin();
    while(it_knoten!=vector_data.end())
    {
        someTestClass *tmp = (*it_knoten);
        delete tmp;
        tmp=0;
        it_knoten = vector_data.erase(it_knoten);
    }

    ///Method 2
    while(!vector_data.empty())
    {
        delete vector_data.back();
        vector_data.pop_back();
    }


    cout<<"end\n";
    cin.get();
    return 0;
}
I use Code::Blocks with gcc on Windows 7 64bit.
I hope you know whats wrong with it ;)
greetings
Last edited by freetimecoder on Fri Apr 22, 2011 3:17 pm, edited 1 time in total.
Radikalizm
Posts: 1215
Joined: Tue Jan 09, 2007 7:03 pm
Location: Leuven, Belgium

Post by Radikalizm »

Haven't inspected your code thoroughly yet, but does this happen in both debug and release builds?
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

Code: Select all

#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;

class someTestClass
{
private:
    double someData;
public:
    someTestClass()
    {
        someData = rand()/2.0;
    }
    ~someTestClass()
    {
    }
};

int main()
{
    vector<someTestClass*> vector_data;

    cout<<"creating\n";
    while(vector_data.size()<1000)
    {
        someTestClass *temp = new someTestClass();
        vector_data.push_back(temp);
    }


    cout<<"deleting\n";

    //Of course both methods do not work together, so comment or uncomment them
    ///Method 1
    vector<someTestClass*>::iterator it_knoten = vector_data.begin();
    while(it_knoten!=vector_data.end())
    {
        someTestClass *tmp = (*it_knoten);
        delete tmp;
        tmp=0;
        vector_data.erase(it_knoten);
    }

    cout<<"end\n";
    return 0;
}
works as a charm for me, tested on valgrind, no leaks occurred.
Working on game: Marrbles (Currently stopped).
Radikalizm
Posts: 1215
Joined: Tue Jan 09, 2007 7:03 pm
Location: Leuven, Belgium

Post by Radikalizm »

That's exactly why I think it has something to do with debug symbols (if it's actually a debug build), I couldn't see any possible leaks myself

If it's not that, then I'm really clueless
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

No debug or release modes change nothing.
I edited the code above, forgot to include cstdlib and added a cin.get at the end so the programm does not just terminate. After the programm ends everything is cleaned up right, but before that the memory is still occupied.

greetings
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

freetimecoder wrote:No debug or release modes change nothing.
I edited the code above, forgot to include cstdlib and added a cin.get at the end so the programm does not just terminate. After the programm ends everything is cleaned up right, but before that the memory is still occupied.

greetings
If you'd add the same amount of things one more time to that vector and delete you'd see that the memory doesn't grow. So I don't think it is leaking anything.
Working on game: Marrbles (Currently stopped).
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

Hm right. The memory at the end stays the same, but I still do not know why it is so much. When I use the vector within another {} the memory amount is ok because the vector is completly deleted, but shouldn't the emptied vector use the same memory like on creation?

greetings
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

http://bytes.com/topic/c/answers/840262 ... ers-vector

Heres what I found on google. Makes sense to me.
Working on game: Marrbles (Currently stopped).
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

Yea that would make sens, however instead of using old memory again my programm just uses more memory :( I can't show the actual code, since it is for a competition. But at least I now have a way to keep memory usage down. I found the answer when trying to envelop the vector in an {} block. Upon complete deletion of the vector the memory is freed. Back in my original programm I now delete the objects which contain the vectors and so the memory is completly freed. That gives me the results I expected. The programm now uses only around 22mb ram instead of 2 gb which made it crash...

Not a elegant solution but a working one.

So back to fixing the problem elegant :D
When I use the vector and add objects it uses new memory. When I delete the pointers from the vector and the objects itself the programm tries to retain reserved memory for later use. But instead of using this memory first it allocates new memory and that is where the problem lies.

I figured out it has something to do with the definition space.
This works fine:

Code: Select all

    vector<someTestClass*> vector_data;
    //Some sample space
    {
        while(vector_data.size()<100000)
        {
            someTestClass *temp = new someTestClass();
            vector_data.push_back(temp);
        }
   
        //Peak memory usage here
    
        while(!vector_data.empty())
        {
            delete vector_data.back();
            vector_data.pop_back();
        }

        while(vector_data.size()<100000)
        {
            someTestClass *temp = new someTestClass();
            vector_data.push_back(temp);
        }
    
        //Same peak memory usage here
    }//End of sample space

However something like this makes the memory usage jump up:

Code: Select all

    vector<someTestClass*> vector_data;
    //Some sample space
    {
        while(vector_data.size()<100000)
        {
            someTestClass *temp = new someTestClass();
            vector_data.push_back(temp);
        }
   
        //Peak memory usage here
    
        while(!vector_data.empty())
        {
            delete vector_data.back();
            vector_data.pop_back();
        }

    }//End of sample space

    while(vector_data.size()<100000)
    {
        someTestClass *temp = new someTestClass();
        vector_data.push_back(temp);
    }

    //Much higher peak memory usage here
The sample space of course makes no sense here, but it kind of represents the situation in my main code.

edit: By the way is "space" the right word?

greetings
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Vectors do not release their memory before their object is destroyed. I think one trick to force it to drop memory earlier is by creating an empty vector in some scope and swap() it with the vector which you want to have give up it's memory . So now your original vector is empty and the one in the scope will release as the object is removed.

Then again you often don't even want to release memory unnecessary as allocating and releasing is an expensive operation. So usually it's not bad (at least in games) to get up to the full memory which your application will need right at the start and keep it around until the program quits.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

Ah, that explains it. Usually it makes sense but I need to clean the vectors moemory completley so my solution seems acceptable.

Thanks for the help :)
Post Reply