注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

c++的智能指针之四——在工程应用中对C类型数据的控制处理  

2016-08-01 10:40:31|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

c++的智能指针之四——在工程应用中对C类型数据的控制处理

 

在工作中修改别人的代码,遇到了一处使用智能指针的地方,没有注意人家的使用方式,直接就按以往的使用经验开用。一开始没有问题,大家都挺HAPPY,结果第二天,同事说有内存泄露,经过好一阵子查找,才发现了原因,使用智能指针std::shared_ptr时,对方使用的是C的形式,使用了自定义的删除器。无语,自己大意了。不由得想到上面的博文看下面抽出来的:

条款6 :处理不是new的对象要小心。

int* pi = (int*)malloc(4)

shared_ptr<int> sp( pi ) ; //delete马嘴不对malloc驴头。

还有上面的条款910,学会使用删除器和分配器。

这明显就是针对这次现象说的啊。看书时不用脑子 ,干活时不走心,该吃这回亏啊。看看这次实例使用的例子:

auto deleter = [](uvc_frame_t *p) { if (p) uvc_free_frame(p); };

auto frame_mjpeg = std::shared_ptr<uvc_frame_t>(waitPreviewFrame(), deleter);

而这次修改是要增加一个智能指针的使用:

Std::shared_ptr< uvc_frame_t > ptr = std::shared_ptr< uvc_frame_t >(p);//p is uvc_frame_t*

然后做为参数传递进去了,然后就出现了这种情况。

后来明白了改成了:

//p is uvc_frame_t*

Std::shared_ptr< uvc_frame_t > ptr = std::shared_ptr< uvc_frame_t >(p,deleter);

或者直接:

std::shared_ptr< uvc_frame_t >(p,deleter)传递参数就可以了。

另外:

在使用std::shared_ptr智能指针时,遇到了一些模糊的东西,在查找资料后清楚了。

一个是reset release,在程序中使用前者,等同于完全释放智能指针对普通指针的控制权。或者释放本身的普通指针使用权然后获得另外一个普通指针的使用权。

后者Release是老版本的auto_ptr等原有的类似于reset的方法,特别是在C++11BOOST还有TR1中的过渡过程中,还是没有清晰的分辨出来。此为一记。

第二个是对分配器和删除器的使用上,看一下C++11的文档:

// get_deleter example

#include <iostream>

#include <memory>

 

struct D {    // a verbose array deleter:

  void operator()(int* p) {

    std::cout << "[deleter called]\n";

    delete[] p;

  }

};

 

int main () {

  std::shared_ptr<int> foo (new int[10],D());

 

  int * bar = new int[20];

 

  // use foo's deleter to delete bar (which is unmanaged):

  (*std::get_deleter<D>(foo))(bar);

 

  return 0;

  // foo's deleter called automatically

}

再看一个owner_before

// shared_ptr::owner_before

#include <iostream>

#include <memory>

 

int main () {

  int * p = new int (10);

 

  std::shared_ptr<int> a (new int (20));

  std::shared_ptr<int> b (a,p);  // alias constructor

 

  std::cout << "comparing a and b...\n" << std::boolalpha;

  std::cout << "value-based: " << ( !(a<b) && !(b<a) ) << '\n';

  std::cout << "owner-based: " << ( !a.owner_before(b) && !b.owner_before(a) ) << '\n';

 

  delete p;

  return 0;

}

这里注意的是使用了别名(参看C++11 std::shared_ptr的构造函数,最后一个)

aliasing (10)  

template <class U> shared_ptr (const shared_ptr<U>& x, element_type* p) noexcept;

所以说对知识一定要学透,学扎实:

实践是检验真理的唯一标准,形而上,经验主义,教条主义和本本主义是害死人的。

  评论这张
 
阅读(96)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017