智能指针的缺点以及智能指针引发的问题

智能指针的缺点

智能指针是一种用于管理动态内存的工具,它可以自动化内存的分配和释放,从而减少程序员手动管理内存的出错可能性。然而,智能指针也有一些缺点,包括以下几点:

1.性能开销:智能指针需要进行额外的内存管理和引用计数操作,这可能会导致程序的性能下降。相比于原始指针,智能指针需要更多的计算资源和时间来完成内存管理任务。

2.循环引用:如果智能指针被用于管理对象之间的循环引用,就可能会出现内存泄漏的问题。当两个对象相互引用时,它们的引用计数永远不会达到零,因此它们的内存也永远不会被释放。

3.难以调试:由于智能指针管理的内存是自动分配和释放的,因此在程序运行时,很难确定哪个指针指向哪个内存块,以及哪个指针可能导致内存泄漏或悬挂指针等问题。这使得调试非常困难。

4.不适用于某些场景:智能指针通常适用于单线程环境,但在某些多线程或异步环境中,智能指针的使用可能会导致竞态条件或死锁等问题。此外,智能指针也不适用于需要在不同的进程之间共享内存的场景。

综上所述,智能指针虽然在某些情况下可以减少内存管理的工作量,但它也有一些缺点,需要根据具体的应用场景进行选择。

#include<iostream>
#include<memory>
using namespace std;

struct Test
{
    shared_ptr<Test>getSharedPtr()
    {
        return shared_ptr<Test>(this);
    }

    ~Test()
    {
        cout<<"析构函数"<<endl;
    }
};

int main()
{
    shared_ptr<Test> sp1(new Test);
    cout<<"引用个数"<<sp1.use_count()<<endl;
    shared_ptr<Test> sp2 = sp1->use_count()<<endl;
    cout<<"引用个数"<<sp1.use_count()<<endl;
    return 0;
}

//引用个数:1
//引用个数:1
//析构函数
//析构函数

通过输出的结果可以看到一个对象被析构了两次,其原因是这样的:在这个例子中使用同一个指针this构造了两个智能指针对象sp1和sp2,这二者之间是没有任何关系的,因为sp2并不是通过sp1初始化得到实例对象。在离开作用域之后this 将被构造的两个智能指针所各自析构,导致重复析构的错误。

#include<iostream>
#include<memory>
using namespace std;

struct Test
{
    shared_ptr<Test>getSharedPtr()
    {
        return shared_ptr<Test>(this);
    }

    ~Test()
    {
        cout<<"析构函数"<<endl;
    }
};

int main()
{
    shared_ptr<Test> sp1(new Test);
    cout<<"引用个数"<<sp1.use_count()<<endl;
    shared_ptr<Test> sp2 = sp1;
    cout<<"引用个数"<<sp1.use_count()<<endl;
    return 0;
}

//引用个数:1
//引用个数:2
//析构函数

循环引用问题

#include<iostream>
#include<memory>
using namespace std;

class A;
class B;

classA
{
public:
    shared_ptr<B> bptr;
    ~A()
    {
        cout<<"class TA is disstruct..."<<endl;
    }
};

class B
{
public:
    shared_ptr<A> aptr;
    ~B()
    {
    cout<<"class TB is disstruct..."<<endl;
    }

void testPtr()
{
    shared_ptr<A> ap(new A);
    shared_ptr<B> bp(new B);
    cout<<"A的 引用计数:"<<ap.use_count()<<endl;
    cout<<"B的 引用计数:"<<bp.use_count()<<endl;
}
}

int main()
{
    testPtr();
    return 0;
}

A的引用计数:1
B的引用计数:1
A的引用计数:2
B的引用计数:2

共享智能指针ap,bp对A,B实例对象的引用计数变为2,在共享智能指针离开作用域之后引用计数只能减为1,这种情况下不会去删除智能指针管理内存,导致类A,B的实例对象不能被析构,最终造成内存泄漏。通过使用weak_ptr可以解决这个问题,只需要将类A或者类B的任意一个成员改为weak_ptr.

class A
{
public:
    weak_ptr<B>bptr;
    ~A()
    {
        cout<<"A的析构函数"<<endl;
    }
};

class B
{
public:
    shared_ptr<A> aptr;
    ~B()
    {
        cout<<"B的析构函数"<<endl;
    }
};

void testPtr()
{
    shared_ptr<A> ap(new A);
    shared_ptr<B> bp(new B);
    cout<<"A 的引用计数:"<<ap.use_count()<<endl;
    cout<<"B 的引用计数:"<<bp.use_count()<<endl;

    ap->bptr = bp;
    bp->aptr = ap;
    cout<<"A 的引用计数:"<<ap.use_count()<<endl;
    cout<<"B 的引用计数:"<<bp.use_count()<<endl;
}

 

猜你喜欢

转载自blog.csdn.net/four_two_six_/article/details/130887975
今日推荐