简体   繁体   中英

C++ Vectors and Memory Leaks

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?

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;
}

In both pieces of code you've allocated your vector<> on the stack. As such, the vector's destructor will be called when it goes out of scope. I don't know what leak detector you're using, but if it checks for leaks just before main exits it may indeed detect a leak, but it's not really a leak.

Where you get into problems with memory leaks is that the std::vector destructor won't call delete on the items in the vector, though it will call their destructors. Thus vector<int> and vector<MyClass> are fine as the vector holds the actual object and will call it's destructor. On the other hand, if you have vector<MyClass*> , you need to be careful; deleting the vector will not free the memory associated with the MyClass objects to which it points.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM