Where is this code not freeing memory ?

W

wolverine

Hi
Let me first of all tell that this problem is not specific to a
compiler like gcc. It even comes in windows. So please dont regard the
question as off topic.

I am posting a code using stl. I viewed the memory for program
by giving top command
eg: top -d 0.2 -p 'pid'
The pid will be printed out by the program itself.

Now coming to the question. The code is supposed to take around (200000
* 100 * 4 bytes = 76MB) .The top command at halfway point (line 41)
showed around 80MB. Until now it is correct. But after this i start
deleting elements from vector one by one. Then the code is supposed to
take lesser memory. But the top command showed still 80MB.
Why is this ?

I then googled and read in
http://www-1.ibm.com/support/docvie...20&uid=swg21160634&loc=en_US&cs=UTF-8&lang=en
that stl "caches" memory and they gave a work around for it. I tried in
the code. Even that is not working.

Let me tell that valgrind or purify is not showing any leak in the
code. I some how need to free
from stl the memory. Is there any way ? Could any one help me ? I need
a general solution
which is applicable for all stl containers.

The code:


#include <vector>
#include <map>
#include<algorithm>
#include<unistd.h>
#include<iostream>
using namespace std;

//typedef vector <int, __malloc_alloc_template<0> > typIntVec;
//typedef map <long, typIntVec, std::less<long>,
//__malloc_alloc_template<0> > typLongIntVecMap;
typedef vector <int> typIntVec;
typedef map <long, typIntVec> typLongIntVecMap;



int main ()
{
typLongIntVecMap tMap;

cout<<"PID IS:"<<getpid()<<endl;
sleep(2);

cout<<"BEGIN EXECUTION."<<flush;

typLongIntVecMap::iterator tMapItr;
for (long j=1; j<200000; j++)
{
typIntVec vec;

//inserting 100 elements into the vector
for(int i=0; i<100; i++)
{
vec.push_back(i);
}

//put the vector into the map
tMap[j] = vec;

//simply putting a sleep so that we could see the increase in memory
if(j % 40000 == 0)
{
cout<<"."<<flush;
sleep(1);
}
}

cout<<endl<<"MEM IN STABLE POSITION......."<<endl;
cout<<"NOW IT SHOULD DECREASE";
sleep(2);
for (long j=1; j<200000; j++)
{
//get back a reference to the vector inside the map
typIntVec& vecRef = tMap[j];

//delete every element inside the vector
for(int i=0; i<100; i++)
{
typIntVec::iterator itr =
find(vecRef.begin(), vecRef.end(), i);
if(itr != vecRef.end())
{
vecRef.erase(itr);
}
}

//sleeping simple so that we could see the decrease in memory
if(j % 40000 == 0)
{
cout<<"."<<flush;
sleep(1);
}
}

cout<<endl<<"MAP WITH NO ELEMENTS IS IN MEM NOW"<<endl;
sleep(2);
return 0;
}
 
J

joosteto

wolverine wrote:

Ah, there does seem to be real-non-freed memory:
for (long j=1; j<200000; j++)
{
typIntVec vec;

Here, you construct IntVec.
for(int i=0; i<100; i++)
{
vec.push_back(i);
}
Here, you construct 100 int's and put them in the IntVec
tMap[j] = vec;

Here you create a map entry
}
for (long j=1; j<200000; j++)
{
for(int i=0; i<100; i++)
{
typIntVec::iterator itr =
find(vecRef.begin(), vecRef.end(), i);
if(itr != vecRef.end())
{
vecRef.erase(itr);
}
}
You destruct the 100 int's -- but where do you destruct the IntVec?
Where do you destruct the entry in the map?
 
T

Thomas J. Gritzan

wolverine wrote:

Ah, there does seem to be real-non-freed memory:
for (long j=1; j<200000; j++)
{
typIntVec vec;

Here, you construct IntVec.
for(int i=0; i<100; i++)
{
vec.push_back(i);
}
Here, you construct 100 int's and put them in the IntVec
tMap[j] = vec;

Here you create a map entry
}
for (long j=1; j<200000; j++)
{
for(int i=0; i<100; i++)
{
typIntVec::iterator itr =
find(vecRef.begin(), vecRef.end(), i);
if(itr != vecRef.end())
{
vecRef.erase(itr);
}
}
You destruct the 100 int's -- but where do you destruct the IntVec?
Where do you destruct the entry in the map?

In the destructor. It's called RAII.
 
J

joosteto

Thomas said:
wolverine wrote:

Ah, there does seem to be real-non-freed memory:
for (long j=1; j<200000; j++)
{
typIntVec vec;

Here, you construct IntVec.
for(int i=0; i<100; i++)
{
vec.push_back(i);
}
Here, you construct 100 int's and put them in the IntVec
tMap[j] = vec;

Here you create a map entry
}
for (long j=1; j<200000; j++)
{
for(int i=0; i<100; i++)
{
typIntVec::iterator itr =
find(vecRef.begin(), vecRef.end(), i);
if(itr != vecRef.end())
{
vecRef.erase(itr);
}
}
You destruct the 100 int's -- but where do you destruct the IntVec?
Where do you destruct the entry in the map?

In the destructor. It's called RAII.

In who's destructor? Do you mean tMap's destructor? Then we agree, but
that's not what the poster asked.
tMap's destructor is called when main() finishes, and the poster
wondered why de memory wasn't freed *before* main() finishes (and thus
before tMap is destructed).

The cout statements show that the poster thinks that before the end of
main(), there is a "MAP with no enteries". At that point however, no
entry from tMap has been erased, and thus no IntVe has been destructed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top