C++11智能指针管理第三方库分配的内存

由于第三方库返回的分配内存返回的指针一般是原始指针,需要手动释放内存。这时候就可以使用智能指针来自动管理分配的内存了。
下面来模拟一种使用智能指针来管理第三方库的一个情形。事实上这个例子在如MFC、OpenCV等第三方库的使用中十分常见。在下面的例子中,有2个要点值得关注:

  • 对象的生存周期。这是导致资源(包括内存)泄漏的一个重要原因。

  • shared_ptr的用法。

  • 假设有资源R,通过GetHandle()来获取其对象的句柄为我们分配所需要的资源对象Obj。
    如下,在test()中创建了资源Obj数组,假如不采取任何措施,p指向的内存将发生内存泄漏。
    此时我们可以用智能指针来管理内存。这里要警惕下面的错误写法。这个错误是由于shared_ptr的对象周期结束时,其管理的内存将被释放。假如采用guard2,当其调用结束时,sp的生存周期结束,p的内存释放,导致guard2之后p就成为一个野指针了。
    我们可以用gurad的写法,间接的增加shared_ptr的生存周期。
    最好的是采用的写法,其展开后sp将与p的生存周期相同。

#include<iostream>
#include<memory>
#include<cstdlib>

class Obj {
    public:
        Obj() {
            std::cout << "Obj" << std::endl;
        }
        ~Obj() {
            std::cout << "~Obj" << std::endl;
        }
};
struct R {
    void* create() {
            std::cout << "enter create" << std::endl;
            Obj* i = new Obj[5];
            std::cout << "create" << std::endl;
            return i;
    }
    void Release(void* p) {
        std::cout << "enter Release" << std::endl; 
        Obj* p1 = (Obj*)p;
        delete [] p1;
        std::cout << "out Release" << std::endl;
    }
    ~R() {
        std::cout << "~R" << std::endl;
    }
}r;

R* GetHandle() {
    return &r;
}

//错误写法 
//void guard2(void* p) {
//  std::shared_ptr<void> sp(p, [](void* p){GetHandle()->Release(p);});     
//}
//第二种方式 
std::shared_ptr<void> guard(void* p) {
    std::shared_ptr<void> sp(p, [](void* p){GetHandle()->Release(p);}); 
    return  sp; 
}

//第二种方式 
#define GUARD(P) std::shared_ptr<void> p2(p,[](void* p){GetHandle()->Release(p);}); 
void test() {
    void* p = GetHandle() -> create();
//  guard2(p);std::cout << "out gurad2" << std::endl; 
    // auto p2 = guard(p);
//   GUARD(p);
    std::cout << "out test" << std::endl; 
}

int main(){
    test();
    int x;
    std::cin >> x;
    std::cout << "out main" << std::endl;
}
  • 你可以通过注释或去注释来观察对象的创建和释放情况来更深一步的理解。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 原作者:Babu_Abdulsalam 本文翻译自CodeProject,转载请注明出处。 引入### Ooops...
    卡巴拉的树阅读 30,307评论 13 74
  • 专属所有权:unique_ptr 我们大多数场景下用到的应该都是 unique_ptr。 unique_ptr 代...
    wayyyy阅读 4,980评论 0 1
  • 12.1 智能指针 智能指针行为类似普通指针,但它负责自动释放所知的对象。 #include <memory> s...
    龙遁流阅读 3,008评论 0 1
  • 内存管理 C++使用new和delete两个运算符进行内存管理。 使用new进行动态分配和初始化对象 在自由空间内...
    plantom阅读 2,958评论 0 1
  • 近几年出现了一个新名词“月光族”,指的是每月赚的钱还没到下个月月初就被全部用光、花光的一群人。而如今越来越多的年轻...
    宁静致远hfm阅读 1,585评论 0 0

友情链接更多精彩内容