【问题标题】:shared_ptr does not destruct the object at the end of the programshared_ptr 不会在程序结束时破坏对象
【发布时间】:2020-10-09 14:46:40
【问题描述】:

我正在尝试使用智能指针实现双端队列。但是,我注意到在程序结束时,双端队列的节点没有被正确破坏。
代码如下:

#include<iostream>
#include<memory>


class Node
{
  int value;
  std::shared_ptr<Node> next = nullptr;
  std::shared_ptr<Node> prev = nullptr;

public:
  Node() = default;
  Node(int val): value(val) {}
  ~Node()
  {
    std::cout << "Destructor of node: " << value << std::endl;
  }
  friend class Deque;
};

class Deque
{
  using pointer = std::shared_ptr<Node>; 
  pointer head = nullptr;      // pointer to the first element of the queue
  pointer tail = nullptr;      // pointer to the last element of the queue 

public:
  Deque() = default;
  ~Deque(){ std::cout << "Dequeue destructor" << std::endl; }
  
  bool is_empty()
  {
    if (head == nullptr && tail == nullptr )
      return true;
    else
      return false;
  }
  void push_back(const pointer& val)
  {
    if (is_empty())
      {
        head = val;
        tail = val;
      }
    else
      {
        val->prev = tail;
        tail->next = val;
        tail = val;
      }
  }
};



int main()
{
  Deque DEQ;  
  auto node1 = std::make_shared< Node >(1);
  auto node2 = std::make_shared< Node >(2);
  auto node3 = std::make_shared< Node >(3);

  DEQ.push_back(node1);
  DEQ.push_back(node2);

  std::cout << "Use count node1 = " << node1.use_count() << std::endl;
  std::cout << "Use count node2 = " << node2.use_count() << std::endl;
  std::cout << "Use count node3 = " << node3.use_count() << std::endl;
 
  return 0;
}

输出如下:

Use count node1 = 3
Use count node2 = 3
Use count node3 = 1
Destructor of node: 3
Dequeue destructor

当我将node1node2 推入双端队列时,它们不会在程序结束时被破坏,而node3 被正确破坏。
我假设问题是node1node2 的引用计数等于3。你知道我可以如何改变我的实现来解决这个问题吗?谢谢。

【问题讨论】:

  • 查看使用列表的类似question
  • std::shared_ptr&lt;Node&gt; next = nullptr; std::shared_ptr&lt;Node&gt; prev = nullptr; 是您自己脚下的经典拍摄。 ;-) 其中一个应该是std::weak_ptr。 (我会投票给prev。)
  • 如果你用这个建立一个双链表,每个节点都将拥有它的下一个,下一个将拥有它的前任。这产生了一个循环,没有人能够放弃所有权(无需外部干预)。这是循环所有权产生的典型内存泄漏。
  • 当一个对象有一个指向其所有者的指针时,该指针不需要是智能指针,因为没有生命周期问题。
  • shared_ptr 不是这项工作的正确工具。

标签: c++ c++11 queue smart-pointers


【解决方案1】:

我假设问题是node1和node2的引用计数等于3。

你的假设是正确的。共享指针在引用计数降至零之前不会破坏指向的对象。

你知道我可以如何改变我的实现来解决这个问题吗?

所有权图中没有循环。例如,您可以在列表的一个方向使用拥有智能指针,而在另一个方向使用非拥有指针(可能是弱指针)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    相关资源
    最近更新 更多