C++ shared_ptr使用时的几个问题

shared_ptr.是c++为了提高指针安全性而添加的智能指针,方便了内存管理。功能强大,但是也要注意以下问题:

1、不能用普通指针给它赋值

	int* pIntValue = new int;
	shared_ptr<int> shPtr= pIntValue;  // 语法错误
	shPtr = pIntValue;  // 语法错误

2、shared_ptr多次引用同一数据,会导致两次释放同一内存。

int* pIntArr = new int[10];
shared_ptr<int> sp1(pIntArr );
shared_ptr<int> sp2(pIntArr );// 析构时两次释放同一内存

3、使用shared_ptr包装this指针带来。

错误作法:

class Test
{
public:
	Test() {};
	~Test() {};
public:
  shared_ptr<Test> sget()
  {
    return shared_ptr<Test>(this);
  }
};
Test one;
shared_ptr<Test> two=  one.sget();// 两次释放t对象破坏堆栈
// 两次释放one对象破坏堆栈!!!!!
// 两次释放one对象破坏堆栈!!!!!
// 两次释放one对象破坏堆栈!!!!!

正确作法:

class Test: public enable_shared_from_this<Test>
{
public:
	Test() {};
	~Test() {};
public:
  shared_ptr<Test> sget()
  {
    return shared_from_this();
  }
};
Test one;
shared_ptr<Test> two=  one.sget();// 正确了。

4、shared_ptr循环引用导致内存泄露。

class father;
class son; 

typedef shared_ptr<father> father_ptr;
typedef shared_ptr<son> son_ptr; 

class father
{
public:
   ~father() {}
   son_ptr m_son;
};
class son
{
public:
   ~son() {}
   father_ptr m_father;
};

  father_ptr f(new father());
  son_ptr s(new son);
  f->m_father= s;
  s->m_son= f;

f的引用计数为2,s的计数也为2,退出时,shared_ptr所作操作就是简单的将计数减1,如果为0则释放,显然,这个情况下,引用计数不为0,于是造成f和s所指向的内存得不到释放,导致内存泄露。

5、在多线程程序中使用shared_ptr的问题。

class Test
{
public:
  Test() {}
  ~Test() {}
  // 更多的函数定义…
};
void thread_fun(shared_ptr<Test> sp)
{
  // !!!在这大量使用sp指针.
  shared_ptr<Test> tmp = sp;
}
shared_ptr<Test> sp1(new Test);

thread t1(bind(&fun, sp1));
thread t2(bind(&fun, sp1));
t1.join();
t2.join();

由于多线程同时访问智能指针,并将其赋值到其它同类智能指针时,可能发生两个线程同时在操作引用计数,而导致计数失败或无效等情况。
使用weak_ptr可以解决类多线程中的问题。

void fun(weak_ptr<Test> wp)
{
  shared_ptr<Test> sp = wp.lock;
  if (sp)
  {
    // 在这里可以安全的使用sp指针.
  }
  else
  {
    // 指针无效
  }
} 
发布了43 篇原创文章 · 获赞 9 · 访问量 2650

猜你喜欢

转载自blog.csdn.net/x879014419/article/details/105271346