Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ memory leak when using std::string in shared memory array

I have this class

class LayoutEntry
{
  unsigned int id_;
  string name_;  
  bool isInput_;
};

The copy constructor looks like this:

LayoutEntry(const LayoutEntry &other)
        : id_(other.id_),
        name_(other.name_), 
        isInput_(other.isInput_)
    {
    }

Objects of this class are put inside a map within another class

class DataLayoutDescription 
{
    unsigned int sz_;
    set<LayoutEntry, SortByOffset> impl;

    // HERE!!!
    map<unsigned int, LayoutEntry> mapById;

The copy constructor of this class looks like this:

DataLayoutDescription::DataLayoutDescription(const DataLayoutDescription &other)
    :sz_(other.sz_), impl(other.impl), mapById(other.mapById)
{   
}

Now the question:

  • I Get a memory leak for each LayoutEntry when run like printed
  • If I remove mapById(other.mapById) in the copy constructor of DataLayoutDescription then there is no memleak
  • If I remove name_(other.name_), The memory leaks are also gone

Why?

EDIT

For Testing I use BOOST::UnitTest at the end I get a memory leak dump

C:\wc\05_EAPGit\Debug>EapLibTest.exe --run-test=SharedVectorTest
Running 7 test cases...

*** No errors detected
Detected memory leaks!
Dumping objects ->
{1378} normal block at 0x005815C0, 16 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
{1377} normal block at 0x00581580, 16 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
{1376} normal block at 0x00581540, 16 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

Possible Reason? I persist the DataLayoutDescription in a shared memory area using this method

void DataLayoutDescription::Save(LayoutEntry *les, unsigned int maxEntries) const
{
    int n = std::max(impl.size(), maxEntries);
    int i = 0;
    for (DataLayoutDescription::iterator it = begin(); it != end(); ++it)
    {
        les[i] = *it;  // Source of memory leak here???
        ++i;
    }
}

I dereference the iterator ant store a copy of this in the array that is located in the shared memory region. Is there something wrong? The shared memory is deleted on exit.

Furhter Trackdown The class LayoutEntry is placed in an array within a shared memory area and contains a string. The reason for the memory leak is that the string gets resized. Thus it allocates more memory on the heap. Now I guess that this memroy will not be freed since the original memory is located in the shared memory. Could this be the reason? Next thing I will try to remove the string and replace it with an char array of fixed length.

... after several minutes

This was it. After replacing the string with a fixed array of char the memory leak dissapeared. Hope this helps someone.

like image 787
schoetbi Avatar asked May 17 '11 13:05

schoetbi


People also ask

Why am I getting memory leaks C++?

Memory leakage occurs in C++ when programmers allocates memory by using new keyword and forgets to deallocate the memory by using delete() function or delete[] operator. One of the most memory leakage occurs in C++ by using wrong delete operator.

Does C have memory leak?

Master C and Embedded C Programming- Learn as you goThe memory leak occurs, when a piece of memory which was previously allocated by the programmer. Then it is not deallocated properly by programmer. That memory is no longer in use by the program. So that place is reserved for no reason.

What is memory leak how this situation can be avoided?

Memory leak occurs when programmers create a memory in heap and forget to delete it. The consequences of memory leak is that it reduces the performance of the computer by reducing the amount of available memory.


3 Answers

It looks like the memory leak that was introduced in Visual Studio 2010 C++ standard library, fixed with SP1. If it's your compiler (without SP1) that's certainly the problem.

See also those answers : STL container leak

like image 106
Klaim Avatar answered Oct 16 '22 17:10

Klaim


Assuming that when you say you have a memory leak, you mean some checker like Purify or valgrind is telling you so, the most likely scenario is that somehow you're leaking LayoutEntry objects, NOT string objects directly. I got bitten by this once and got confused because my own object was getting leaked, but the leak was tagged (by valgrind) to std::string which made it harder to find.

Alternately it may just be detecting a growth. Did you try doing a clear on your map prior to exiting?

like image 29
Mark B Avatar answered Oct 16 '22 17:10

Mark B


The reason for the leak was the LayoutEntry class that stores a string. The base object (before modification) was placed in an array within a shared memory area. After altering the string a resize operation was performed, this memory was lost. After replacing the string by an array of chars (fixed length) the memory leak went away. I am happy now but ask myself if the string class does something wrong, or is there a way to put a custom allocator into the std::string? I will not need this because I will go with the char array but I am just curious if something like this would work and weather I am right with this assumtions?

This is the modified class

class LayoutEntry
{
  unsigned int id_;
  char name_[128];  
  bool isInput_;
};

Thanks everybody for your help! The tips for debugging the memory leak helped me a lot.

like image 3
schoetbi Avatar answered Oct 16 '22 17:10

schoetbi