zoukankan      html  css  js  c++  java
  • 智能指针的循环引用与解决

    智能指针的循环引用

    class Node
    {
    public:
    	shared_ptr<Node> left;
    	shared_ptr<Node> right;
    
    	Node(int v)
    	{
    		this->value = v;
    		cout << "Constructor" << endl;
    	}
    	~Node()
    	{
    		cout << "Destructor" << endl;
    	}
    private:
    	int value;
    };
    
    int main()
    {
    	shared_ptr<Node> root = std::make_shared<Node>(4);
    
    	root->left = std::make_shared<Node>(2);
    	root->right = std::make_shared<Node>(3);
    
    	return 0;
    }
    

    上面的程序不会有问题,调用三次构造函数,三次析构函数。

    下面增加一个指向父节点的指针。

    class Node
    {
    public:
    	shared_ptr<Node> left;
    	shared_ptr<Node> right;
    	shared_ptr<Node> parent;
    	Node(int v)
    	{
    		this->value = v;
    		cout << "Constructor" << endl;
    	}
    	~Node()
    	{
    		cout << "Destructor" << endl;
    	}
    private:
    	int value;
    };
    
    int main()
    {
    	shared_ptr<Node> root = std::make_shared<Node>(4);
    
    	root->left = std::make_shared<Node>(2);
    	root->left->parent = root;  //强引用计数加1
    	root->right = std::make_shared<Node>(3);
    	root->right->parent = root;  //强引用计数加1
    
    	cout << "root reference count = " << root.use_count() << endl;
    	cout << "left reference count = " << root->left.use_count() << endl;
    	cout << "right reference count = " << root->right.use_count() << endl;
    	return 0;
    }
    
    

    调用了三次构造函数,但是没用调用析构函数,这就导致了内存泄漏。
    shared_ptr的循环引用定义:
    当两个对象(主体是对象)使用shared_ptr相互引用时,那么当超出范围时,都不会删除内存。发生这种情况的原因是shared_ptr在其析构函数中递减关联内存的引用计数后,检查count是否为0,如果不为0,析构函数就不会释放相应的内存。当出现了循环引用后,就会发现count的值总是不为0。
    这里我用goodnotes画了两张图,希望能把这个过程解释清楚:

    那么如何解决这个问题?
    使用weak_ptr
    下面使用weak_ptr改进二叉树。weak_ptr不会导致强引用计数增加。

      class Node
    {
    public:
    	shared_ptr<Node> left;
    	shared_ptr<Node> right;
    	//shared_ptr<Node> parent;
    	weak_ptr<Node> parent;
    	Node(int v)
    	{
    		this->value = v;
    		cout << "Constructor" << endl;
    	}
    	~Node()
    	{
    		cout << "Destructor" << endl;
    	}
    private:
    	int value;
    };
    
    int main()
    {
    	shared_ptr<Node> root = std::make_shared<Node>(4);
    
    	root->left = std::make_shared<Node>(2);
    	root->left->parent = root;  //强引用计数加1
    	root->right = std::make_shared<Node>(3);
    	root->right->parent = root;  //强引用计数加1
    	
    	cout << "root reference count = " << root.use_count() << endl;
    	cout << "left reference count = " << root->left.use_count() << endl;
    	cout << "right reference count = " << root->right.use_count() << endl;
    	return 0;
    }
    
  • 相关阅读:
    [CF724G]Xor-matic Number of the Graph
    [SOJ #537]不包含 [CF102129I]Incomparable Pairs(2019-8-6考试)
    [SOJ #538]好数 [CC]FAVNUM(2019-8-6考试)
    [洛谷P4052][JSOI2007]文本生成器
    [洛谷P3966][TJOI2013]单词
    [洛谷P5158]【模板】多项式快速插值
    [洛谷P3227][HNOI2013]切糕
    【bzoj】3477: [Usaco2014 Mar]Sabotage 01分数规划
    【SPOJ
    【以前的空间】系列
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/13181122.html
Copyright © 2011-2022 走看看