shared_ptr内存泄漏没有删除操作符

时间:2014-07-30 03:56:18

标签: c++ c++11 memory-management memory-leaks shared-ptr

我实现了一个简单的结构:

struct ListenerNode
{
    ListenerNode() : previous(nullptr), next(nullptr), listener(nullptr), once(false) {}
    std::shared_ptr<ListenerNode> previous;
    std::shared_ptr<ListenerNode> next;
    std::function<void(int)> listener;
    bool once;
};

这将代表场景图实现中的一个实体。我观察到的奇怪行为是当我使用结构时,就像:

int main(int argc, char** argv)
{
    ListenerNode n;
}

它会泄漏内存,但当我使用它时:

int main(int argc, char** argv)
{
    ListenerNode* n = new ListenerNode();
    delete n;
}

它不会泄漏内存!我不明白这里发生了什么。我总是认为当变量超出范围时,不使用new创建一个类/结构的实例就会立即调用析构函数。

有人可以向我解释一下这里发生了什么吗?我也没有看到任何明显的参考增量。

2 个答案:

答案 0 :(得分:7)

根据您的评论,您可以测试内存泄漏,如下面的代码段所示:

int main(int argc, char** argv) 
{
    ListenerNode n;
    _CrtDumpMemoryLeaks();
}

在这种情况下,在调用_CrtDumpMemoryLeaks()时,n尚未超出范围。您可以毫无问题地在n之后访问_CrtDumpMemoryLeaks()的内容。在遇到n的右括号后,main()被破坏。

如果你添加一对额外的大括号:

int main(int argc, char** argv) 
{
    { ListenerNode n; }
    _CrtDumpMemoryLeaks();
}

然后,当遇到额外的右括号时,n被破坏。当您拨打_CrtDumpMemoryLeaks()时,n根本无法访问,因为它已经超出了范围。

答案 1 :(得分:0)

如果您在班级中创建列表,则会泄漏内存。永远不要使用shared_ptr创建周期(就像你使用next / previous一样),它们不会删除任何内容。

您不需要使用nullptr初始化shard_ptr。