1

I have following problem:

When I use std::vector with built-ins i don't get a memory but if I use classes I get memory leak. To illustrate:

//No leak
std::vector<double>* vecPtr1=new std::vector<double>();
//add some elements
delete vecPtr1;

//Leaks some memory but not all
std::vector<SomeClass>* vecPtr2=new std::vector<SomeClass>();
//add some elements with vecPtr2->push_back(SomeClass());
delete vecPtr2;

As far as I understand it delete should call the destructor of std::vector which should in turn call the destructor of SomeClass -> no leak. I have invested some thought and testing into this and the same behaviour happens if I use std::vector in a scope such as here:

{
  std::vector<SomeClass> vector;
  //add elements as before
}
//memory is still used here

I'm using gcc 4.6.1 under Ubuntu 11.10. Is something amiss in my library or do I have a misconception how std::vector destructs elements?

For clarification my complete code with SomeClass replaced with std::pair (yes I know some parts are hacked but it's just an example):

#include <iostream>
#include <vector>
#include <utility>

int main()
{
    std::string inString;
    std::cout<<"Started"<<std::endl;
    //wait
    std::cin>>inString;
    {
        //assign vector
        std::vector<std::pair<std::string,unsigned int> > vec=std::vector<std::pair<std::string,unsigned int> >();
        //push elements
        for(unsigned int i=0;i<1e7;++i)
        {
            vec.push_back(std::pair<std::string,unsigned int>("something",i));
        }
        std::cout<<"Created vector with capacity: "<<vec.capacity()<<std::endl;
        //wait
        std::cin>>inString;
    }
    //vec should go out of scope but not all memory gets freed
    std::cout<<"Deleted vector"<<std::endl;
    //wait
    std::cin>>inString;
    std::cout<<"Shutting down"<<std::endl;

    return 0;
}
denahiro
  • 1,211
  • 7
  • 10
  • 2
    How do you detect memory leak? And more importantly, you have to give some code of you `SomeClass`, because the implementation of constructors and destructors may cause unexpected memory behavior – weidi Jun 04 '12 at 09:12
  • @weidi First I just looked at the memory usage with ps (bad, I know). 'Valgrind --tool=memcheck --leak-check=yes' told me not to worry 'total heap usage: 109 allocs, 109 frees, 7,506 bytes allocated'. But if I run the program once until "_Deleted vector_" and then start a second instance, linux starts filling the swap, which for my understanding means the memory is still in use. – denahiro Jun 04 '12 at 11:13
  • "But if I run the program once until "Deleted vector" and then start a second instance, linux starts filling the swap, which for my understanding means the memory is still in use." - your starting assumptions are incorrect. Do not confuse your memory management with the operating system's memory management. – Joe Jun 04 '12 at 12:59

3 Answers3

7

First of all, you should not create object of vector dynamically. That is simply a bad idea. That is, use automatic vector:

std::vector<SomeClass> classes; //automatic object

Anyway, in your case, I guess the problem lies with the class SomeClass.

I guess this class manages memory and has not implemented at least one of the following properly:

  • Copy-constructor
  • Copy-assignment
  • Destructor

If you're using C++11, then there are two more members:

  • Move-constructor
  • Move-assignment

I would suggest you to read these:

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
3

There shouldn't be any leaks there, provided SomeClass has a correct destructor implemented.

Do you have the copy constructor and assignment operator implemented? Is the destructor clearing all memory it owns?

Also, how do you know you're leaking memory. Are you using a tool like Valgrind or Purify, or just looking at the memory location?

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
0

The problem is "SomeClass".

It is very likely that it will allocate memory which is NOT release on destruction. IT would help if you publish your "SomeClass"

stefan bachert
  • 9,413
  • 4
  • 33
  • 40