cpx
cpx

Reputation: 17557

Memory leaks with recursive function using std::unique_ptr

I haven't used a std::unique_ptr before, so this is kind of my first attempt to trying to use it in recursion call as following:

#define CRTDBG_MAP_ALLOC

#include <stdlib.h>
#include <crtdbg.h>
#include <memory>

struct S {
    S(int X = 0, int Y = 0):x(X), y(Y) {}
    int x;
    int y;
    std::unique_ptr<S> p;
};

void Bar(int i, std::unique_ptr<S> &sp)
{   
    i--;

    sp->p = std::unique_ptr<S>(new S(i, 0)); 

    if (i > 0)
        Bar(i, sp->p);
}

int main()
{
    std::unique_ptr<S> b (new S());
    Bar(5, b);

    // Detects memory leaks
    _CrtDumpMemoryLeaks();
}

At the end of program. I find that whatever memory I allocated wasn't freed according to _CrtDumpMemoryLeaks(); in Visual C++ 2012 x86 running on Windows 8 x64.

Upvotes: 1

Views: 985

Answers (2)

Yochai Timmer
Yochai Timmer

Reputation: 49251

b hasn't been destroyed yet, so it isn't getting freed.

Jus put it in a block, and check for memory leaks after that block:

int main()
{
    {
       std::unique_ptr<S> b(new S());
        Bar(5, b);
    }

    _CrtDumpMemoryLeaks(); // b is destroyed at the end of the block
}

Upvotes: 2

Marco A.
Marco A.

Reputation: 43662

Everything will be destroyed correctly at the end of the proper scopes but you're checking for memory leaks before the destructor for b gets called:

struct S {
    S(int X = 0, int Y = 0) :x(X), y(Y) { std::cout << "built x=" << x << std::endl;  }
    ~S() { std::cout << "destroyed x=" << x << std::endl; }
    int x;
    int y;
    std::unique_ptr<S> p;
};

void Bar(int i, std::unique_ptr<S> &sp)
{
    i--;

    sp->p = std::unique_ptr<S>(new S(i, 0));

    if (i > 0)
        Bar(i, sp->p);
}

int main()
{
    std::unique_ptr<S> b(new S());
    Bar(5, b);

    _CrtDumpMemoryLeaks(); // b hasn't been destroyed yet!
}

Output:

built x=0
built x=4
built x=3
built x=2
built x=1
built x=0
["your code is leaking" dump]
destroyed x=0
destroyed x=4
destroyed x=3
destroyed x=2
destroyed x=1
destroyed x=0

Upvotes: 2

Related Questions