【问题标题】:Memory leaks with recursive function using std::unique_ptr使用 std::unique_ptr 递归函数的内存泄漏
【发布时间】:2014-12-21 17:01:47
【问题描述】:

我之前没有使用过std::unique_ptr,所以这是我第一次尝试在递归调用中使用它,如下所示:

#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();
}

在程序结束时。我发现我分配的任何内存都没有根据在 Windows 8 x64 上运行的 Visual C++ 2012 x86 中的_CrtDumpMemoryLeaks(); 释放。

【问题讨论】:

  • b 在您调用该内存泄漏函数时仍然存在。
  • 只是b 的析构函数在超出范围之前不会运行,即在您调用_CrtDumpMemoryLeaks() 之后
  • 啊,我将b 移到了一个全新的函数中,并且做对了。

标签: c++ c++11 recursion memory-leaks unique-ptr


【解决方案1】:

b 还没有被销毁,所以它没有被释放。

只要把它放在一个块中,然后在那个块之后检查内存泄漏:

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

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

【讨论】:

    【解决方案2】:

    一切都将在适当的作用域结束时正确销毁,但您要检查内存泄漏b 的析构函数被调用之前:

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

    输出:

    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
    

    【讨论】:

    • 添加析构函数调用有助于显示b 在调用CrtDumpMemoryLeaks 函数时是否仍然存在。
    猜你喜欢
    • 2012-10-31
    • 2016-06-07
    • 2021-07-11
    • 2013-06-15
    • 2016-03-15
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多