C++ Vectors and Memory Leaks

cmemory-leaksstd

I've read somewhere sometime ago that vectors cause memory leaks depending on how they're used, but I'd like to ask just to be sure:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

int main()
{
    vector<somePtr*> listPtrs;

    return 0;
    //Detects memory leaks
}

And this doesn't detect anything:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

int main()
{
    {
        vector<somePtr*> listPtrs;
    }

    return 0;
    //No memory leaks detected
}

The objects are being deleted from the vectors before clearing the pointers.
I think I remember reading that vectors and lists and other std containers are auto-deleted after the block they're in, so in the example 1 I get the memory leak because the memory leak function is called before the block ends, so the vector is still alive and causing it.

I'm not sure about it though, it's been quite a while since I think I read this, and I could only find questions about objects not being deleted, just pointers being removed.

Is this true? And will I get memory leaks if I use global classes that contains vectors and lists?

Best Answer

The point at which you call _CrtDumpMemoryLeaks is important as all used memory may not have been released yet. For instance in the example below if you call _CrtDumpMemoryLeaks() before listPtrs goes out of scope any memory it has allocated will be included in the list of leaked memory.

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>

int main()
{
    std::vector<struct Foo*> listPtrs;

    _CrtDumpMemoryLeaks();

    return 0;
}

In the example below listPtrs goes out of scope prior to calling _CrtDumpMemoryLeaks so any memory it has allocated will be freed and not listed in the blocks of leaked memory.

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>

int main()
{
    {
        std::vector<struct Foo*> listPtrs;
    }

    _CrtDumpMemoryLeaks();

    return 0;
}

Likewise if you call _CrtDumpMemoryLeaks after main has returned any resources allocated by std::vector should be released. Again this is because listPtrs has now gone out of scope and the destructor of std::vector has been called.

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>

// Call _CrtDumpMemoryLeaks after main has returned and before program terminates.
struct AtExit
{
    ~AtExit() { _CrtDumpMemoryLeaks(); }
} doAtExit;

int main()
{
    std::vector<struct Foo*> listPtrs;

    return 0;
}

I highly recommend using smart pointers instead of naked pointers. It keeps them warm in the winter and you won't have to worry about using delete.

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <vector>
#include <memory>

// Call _CrtDumpMemoryLeaks after main has returned and before program terminates.
struct AtExit
{
    ~AtExit() { _CrtDumpMemoryLeaks(); }
} doAtExit;

int main()
{
    std::vector<std::unique_ptr<struct Foo*>> listPtrs;

    return 0;
}