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;
}
  • 你可以通过注释或去注释来观察对象的创建和释放情况来更深一步的理解。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

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