使用boost::shared_ptr的教训
来源:互联网 发布:mac 无线投影到显示器 编辑:程序博客网 时间:2024/05/19 20:56
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);}
0 0
- 使用boost::shared_ptr的教训
- boost::shared_ptr的多线程使用陷阱
- 使用boost::shared_ptr做为线程的参数
- boost::shared_ptr使用技巧
- boost 库的 shared_ptr
- boost::shared_ptr的使用方法
- boost::shared_ptr的使用方法
- boost shared_ptr的使用方法
- boost::shared_ptr的使用方法
- 智能指针tr1::shared_ptr、boost::shared_ptr使用
- boost shared_ptr 使用注意点。
- Boost:使用shared_array和shared_ptr
- boost智能指针shared_ptr使用要注意的几个问题
- boost shared_ptr的小技巧
- Boost 关于 shared_ptr 的学习心得
- boost的shared_ptr循环引用
- boost::shared_ptr的线程安全性
- boost的shared_ptr循环引用
- 关于HTML中ID和name的区别
- oracle 实例启动时报 ORA-01157,ORA-01110解决
- SQL server 远程连接失败
- Hadoop Core 学习笔记(一) SequenceFile文件写入和读取Writable数据
- 栈的经典问题:括号配对
- 使用boost::shared_ptr的教训
- python 学习笔记——set() class 集合类型
- MySQL-connection-1
- ubuntu eclipse tomcat 运行web project 遇到的若干问题及解决方案
- NGUI研究院之与图片拼接的1像素接缝(原文转载)
- java 实现选择排序
- bzoj1076: [SCOI2008]奖励关 压状dp
- 关于“The type *** is not accessible due to restriction on required library”问题的解决
- Android 使用【AIDL】调用外部服务