【问题标题】:shared_ptr memory leak without delete operator没有删除操作符的 shared_ptr 内存泄漏
【发布时间】:2014-09-21 14:30:39
【问题描述】:

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

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 的类/结构的实例会立即调用析构函数。

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

【问题讨论】:

  • 你怎么知道它在泄漏?
  • _CrtDumpMemoryLeaks()
  • 你在哪里打电话给_CrtDumpMemoryLeaks()
  • 如果你用一对额外的大括号括住ListenerNode n; 怎么办?
  • 此时n 还没有被破坏。

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


【解决方案1】:

根据您的评论,您在以下 sn-p 中测试内存泄漏:

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

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

如果你多加一对大括号:

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

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

【讨论】:

    【解决方案2】:

    如果你用你的班级创建一个列表,你会泄漏内存。永远不要用 shared_ptr 创建循环(就像你对下一个/上一个所做的那样),它们不会删除任何东西。

    你不需要用 nullptr 初始化 shard_ptr。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      • 2011-02-13
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 2020-05-11
      相关资源
      最近更新 更多