首页 > 解决方案 > 这种对共享指针向量的回退是否会导致内存泄漏?

问题描述

我正在为我所在的项目制作节点编辑器,并且我有一个 std::vector 的共享指针Node,该类具有不同节点类型的派生类。

正如我所说,这是一个共享指针向量(我正在试验智能指针,所以在这方面我有点新手),当我创建一个节点时,执行下一个代码:

 DerivedNodeClass* d_node = new DerivedNodeClass();
 nodes.push_back(std::make_shared<Node>((Node*)d_node);

所以这工作正常,但我想知道这种创建节点的方式是否会导致内存泄漏或类似的事情,因为我不确定这是否是创建类并将它们添加到智能指针向量中的“正确方式” .

在我停止使用节点后,我只是迭代了向量调用.reset(),但我仍然不确定我是否做得对。

请注意,任何派生类都Node处理与动态内存相关的任何指针或任何内容。

标签: c++smart-pointers

解决方案


正如您可能知道的那样,共享指针会在最后一个共享指针停止指向数据时自行删除它们指向的数据(最后一个引用被破坏 - 共享指针保留有关有多少共享指针指向内存中存储的该数据的信息) .

在使用共享指针时,您可能会遇到内存泄漏问题的唯一方法是,例如,当您class Wrapper将容器作为实例的容器时class Node,存储在类 Wrapper 的容器中的每个节点都具有对 Wrapper 类的引用(作为 shared_ptr)并且从其他地方有一个 shared_ptr 指向 Wrapper 类的实例(从之前创建实例的地方)。这意味着 Wrapper 类的实例指向 Node 类的实例,同时 Node 类的实例指向 Wrapper 类的实例,并且还有另一个指向 Wrapper 类的实例的指针。(我在这里试着给它画了一个草图: 在销毁之前在销毁之后,它帮助我理解了智能指针)

当您尝试为 Wrapper 类调用析构函数时,它会从创建位置删除 shared_ptr,但容器中的每个 Node 实例都指向 Wrapper 实例。您试图破坏的 Wrapper 类的实例仍然存在 shared_ptr 。这意味着 shared_ptr 中有对这个 Wrapper 类实例的引用,因此破坏这个实例会导致内存泄漏。

如果你想解决这个问题,你应该检查弱指针(https://en.cppreference.com/w/cpp/memory/weak_ptr)。希望我有所帮助。


推荐阅读