OpenCV中使用C++11的智能指针避免内存泄漏问题

写过代码都知道,C#与Java都有自动的垃圾回收机制,可以很大程度上避免内存泄漏,但是C++开发对初学者最大的问题就是内存管理(初始化、分配与回收)。稍微不注意就会导致内存泄漏问题,比C#跟Java要难很多,被吐槽太多。所以C++11之后有了智能指针,用它你就可以不用担心内存管理问题,它可以自动完成内存管理与回收,最大程度避免内存泄漏问题。C++11中提供了三种不同类型的智能指针,分别是:

共享智能指针std::shared_ptr独占智能指针std::unique_ptr弱智能指针std::weak_ptr

使用时候需要引入头文件。

共享智能指针

共享智能指针使用引用计数,每个shared_ptr的拷贝都指向相同的内存,在最后一个shared_ptr被析构的时候,内存被释放。

初始化共享智能指针

初始化共享智能指针有两种方法,第一种是通过new来直接初始化,第二种方式是通过make_shared方法与reset方法来初始化,这部分的代码演示如下:

// make_shared初始化
int a = 1;
std::shared_ptr<int> a1 = std::make_shared<int>(a);
std::cout << "a1: "<<*a1 << std::endl;
// 直接初始化
std::shared_ptr<int> a2 = std::shared_ptr<int>(new int(2));
std::cout << "a2: " << *a2 << std::endl;

一个原始指针最多只能初始化一个智能指针、而且可以从智能指针中通过get方法获取原始指针,这部分的代码演示如下:

// 一个原始指针,只能初始化一个智能指针
int* ptr = new int(12);
std::shared_ptr<int> a3(ptr);
// std::shared_ptra4(ptr); //直接挂了!

// 从智能指针中获取原始指针
int* pp = a3.get();
std::cout << "pp: " << *pp << std::endl;

独占智能指针与弱智能指针

独占智能指针通常用在希望只有一个智能指针管理资源或者数据的场景,不希望共享智能指针来管理数据或者资源的场景。弱智能指针是共享智能指针的助手,主要作用是监视共享智能指针的操作,资源是否释放。

共享智能指针的代码演示

下面是共享智能指针一个典型的应用场景,就是在std::vector中使用共享智能指针来管理容器的对象或者数据。假设有个结构体,对象如下:

typedef struct person {    std::string name;    int age;};

然后初始化std::vector如下:

std::vector<person> persons;
person p3;
p3.name = "opencv4";
p3.age = 20;
person p4;
p4.name = "opencv5";
p4.age = 21;
persons.emplace_back(p3);
persons.emplace_back(p4);

然后有一天有个经常写C#或者Java的人,想更新std::vector结构体里面的属性值,于是它就遍历每个元素,然后开始修改,代码如下:

for (auto item : persons) { // 修改的是副本  item.age = 24;}

测试运行结果如下:

for (auto item : persons) {  std::cout << "item.age: " << item.age << std::endl;}

Image

发现翻车了,原因是C++来说,通过for直接修改的不是引用,而是修改了副本!这个时候,只要改一个地方就立刻好了:

for (auto &item : persons) { // 获取引用地址
    item.age = 24;
}
for (auto item : persons) {
    std::cout << "item.age: " << item.age << std::endl;
}

Image

改用智能指针

在初始化时候使用共享智能指针来完成元素组装,代码演示如下:

std::vector<std::shared_ptr<person>> pps;
person x;
auto p5 = std::make_shared<person>(x);
p5->name = "make_shared";
auto p1 = std::shared_ptr<person>(new person());
auto p2 = std::shared_ptr<person>(new person());
p1->age = 12;
p1->name = "qing";
p2->age = 32;
p2->name = "zhigang";
pps.emplace_back(p1);
pps.emplace_back(p2);
pps.emplace_back(p5);
for (auto item : pps) {
    item->age = 24;
}
for (auto item : pps) {
    std::cout << "item->name: " << item->name << " item->age:" << item->age << std::endl;
}

运行结果如下:

Image

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值