您的位置:首页 > 其它

使用boost::shared_ptr的教训

2015-01-08 22:49 204 查看
boost库的强大,使用过的人都知道。在使用的过程中,多多少少容易出现些使用不对的地方。下面我就说一些我犯的错误,本人犯的错误呢,一般分分钟搞定,一般几天搞不定,最后找到问题才发现就是一个很小或者说 不应该犯的错误。

我共享出来这些问题,希望能帮到需要提醒的朋友们。

首先应该感谢如下:

1、

这个群里的朋友对我的帮助,当然我也因为一个问题被T,被T是因为一个模板类怎么声明为友元类的时候,因为一句“你大爷”,然后就飞了~~

2、感谢

神奇的~这个妹子朋友,我在上面群被T的时候,这个妹子加我给我帮助,一个很厉害的~,令我感到汗颜,再次感谢她给我的帮助。

为什么我的boost::shared_ptr指针的强引用计数明明大于1,为什么对象还是会被释放?

ok!

下面的代码图是我的一个指针管理器的一部分:



这个管理器的目的很简单,你给我指针,我给你存起来,然后给你返回弱指针,这样的目的在于,传递若指针避免对象被其他地方意外的释放。[题外话]当然,如果你想要释放这个若指针里的对象,也是可以的:

boost::weak_ptr<T>::lock().get()


上面的代码纯属手打,如有错误,请参照boost的代码说明。上面的2个方法都是对象方法。

这样就能得到智能指针里的对象,你可以随意使用他,你就是把他释放了,智能指针也不知道。如果你得到上面的代码返回的指针如ptr,如果你使用boost::share_ptr<T>(ptr)来构造一个指针对象,那么这第一个问题,就开始渐渐的浮出水面了。
ok![题外话到此结束]。有可能你在图中发现了:

void Remove(T* p)
这个方法,这还是个私有方法,其实他没什么用,因为第一个问题就是他导致的。全代码为:

void Remove(T* p){
// 现在不在提供这个方法,
// __my_shared_ptr ptr(p);
// Remove(ptr);
}
一开始他为公开方法,因为我使用的集合:

typedef boost::unordered_set<__my_shared_ptr> __my_set;
集合里存着的是boost::share_ptr,所以我天真的以为,我构造一个boost::share_ptr<T>(ptr)传给:

void Remove(__my_shared_ptr p){
Common::__scoped_lock lock(_PointerMgr_mutex);
__my_set::iterator find = _set.find(p);
if (find == _set.end()){
return;
}
__my_shared_ptr ptr = *find;
_set.erase(find);
//ptr.reset();
}


一开始我天真的以为构造一个boost::share_ptr<T>(ptr)然后去调用这个Remove去从set里移除这个对象就可以了,因为 我的想法是,使用相同的对象类型去find,应该比较容易,~~~想法就是如此的单纯幼稚。但是!事实上证明,这么做find的确是find到了一个有效的结果。ok!这里没有问题:

1、因为如果find的对象的引用计数为1,那么erase from set 后智能指针就会删除对象。

2、因为如果find的对象的引用计数大于1, 那么erase from set 后智能指针不会删除对象,这样你可能需要reset,或者出于你的目的,还不想释放这个对象。

当这里执行完毕!,问题开始出现:

void Remove(T* p){
// 现在不在提供这个方法,
// __my_shared_ptr ptr(p);
// Remove(ptr);
}
当执行到"}"这个最后一个大括号的时候,如果上面的1成立,则这个对象被释放2次,如果你很幸运,那么这里会报内存错误。因为构造的ptr智能指针在这个方法里结束了他的生命周期,所以他释放的时候强引用-1,所以自然而然的再次delete。如果上面的2成立,那么你可能在想为什么这个对象会被释放~~~,苦思冥想,最后发现,还是因为这个临时的智能指针对象造成的~

ok!

ok!

那么如何避免这个问题?

其他也不麻烦,把:

void Remove(T* p)
change to:

void Rempve(boost::weak_ptr<T> ptr)
因为一开始当你添加一个指针的时候,你就已经得到了一个弱指针,所以这里传递一个弱指针应该是不太困难的。然后通过:

ptr.lock()
这句代码返回一个:

boost::shared_ptr<T>
这个boost::shared_ptr<T>对象,这个对象就和在set存储的boost::shared_ptr<T>对象是有连接的,共享所以他们的强引用计数也是使用的同一个,不像上面存在的问题,上面的问题的主要原因就是因为2个boost::shared_ptr<T>指针对象是独立的,没有关联的,导致他们互相认不到自己的引用计数。

add一个指针的代码:

__my_weak_ptr Add(T* p, boost::function<void(T*)> func = NULL){
__my_shared_ptr ptr(p, func);
return Add(ptr);
}

__my_weak_ptr Add(const __my_shared_ptr& p){
Common::__scoped_lock lock(_PointerMgr_mutex);
_set.insert(p);
return __my_weak_ptr(p);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: