C++函数中,两个自动释放内存的动态内存申请类

最近做一个事情,实现一个流程交互,其中主交互流程函数中,涉及较多的内存申请,

而健康的函数,都是在函数退出前将手动申请不再需要的内存释放掉,

使用很多方法,都避免不了较多的出错分支时,一堆的if free/delete,代码长而且不好管理

因此,利用C++对象离开作用域会自动调用析构函数的特点,在这儿实现了两个自动释放内存的动态内存申请类

第一个类,只管理内存,不并管理对象

#include <vector>

class XAutoFreeMem
{
protected:
    std::vector<void*> vec_memorys_;

public:
    XAutoFreeMem::XAutoFreeMem() {};

    virtual XAutoFreeMem::~XAutoFreeMem()
    {
        //释放对象时,释放管理的内存
        for(auto item : vec_memorys_){
            free(item);
        }
    }

    //通过此接口来申请内存
    void* malloc_mem(unsigned int nsize)
    {
        void* ptr = malloc(nsize);
        if (nullptr != ptr) {
            vec_memorys_.push_back(ptr);
        }
        return ptr;
    }
};

第二个类,能够同时支持内存管理、对象管理

typedef void (*delete_obj_func)(void*);

class XAutoFreeObject : public XAutoFreeMem
{
private:

    typedef struct object_manager_st
    {
        void* obj_this;
        delete_obj_func delete_ptr;
    }object_manager_st;

protected:
    template<typename T>
    static void free_object(T* p_this)
    {
        delete p_this;
    }
    template<typename T>
    static void free_objects(T* p_this)
    {
        delete []p_this;
    }

protected:
    std::vector<object_manager_st> vec_objects_;

public:
    XAutoFreeObject::XAutoFreeObject() {};

    virtual XAutoFreeObject::~XAutoFreeObject()
    {
        //释放对象时,释放管理的对象
        for(auto item : vec_objects_){
            (*item.delete_ptr)(item.obj_this);
        }
    }

    //对象

    //通过此接口来创建对象
    template<typename T>
    void new_object(T** ppObj)
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T;
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr =(delete_obj_func) & free_object<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        *ppObj = (T*)(stObjMan.obj_this);
        return;
    }

    //通过此接口来创建对象
    template<typename T, typename P>
    void new_object_with_param(T** ppObj, P param)
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T(param);
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr = & free_object<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        *ppObj = (T*)(stObjMan.obj_this);
        return;
    }

    //通过此接口来创建对象,这几个接口使用会麻烦一些,使用示例:std::string* pstr = stAutoManager.new_object<std::string> ();
    template<typename T>
    T* new_object()
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T;
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr =(delete_obj_func) & free_object<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        return (T*)(stObjMan.obj_this);
    }

    //通过此接口来创建对象
    template<typename T, typename P>
    T* new_object_with_param(P param)
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T(param);
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr = & free_object<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        return (T*)(stObjMan.obj_this);
    }

    //对象数组

    //通过此接口来创建对象数组
    template<typename T>
    void new_objects(T** ppObj, int num)
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T[num];
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr =(delete_obj_func) & free_objects<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        *ppObj = (T*)(stObjMan.obj_this);
        return;
    }

    //通过此接口来创建对象数组
    template<typename T, typename P>
    void new_objects_with_param(T** ppObj, int num, P param)
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T[num](param);
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr = & free_object<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        *ppObj = (T*)(stObjMan.obj_this);
        return;
    }

    //通过此接口来创建对象数组
    template<typename T>
    T* new_objects(int num)
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T[num];
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr =(delete_obj_func) & free_object<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        return (T*)(stObjMan.obj_this);
    }

    //通过此接口来创建对象数组
    template<typename T, typename P>
    T* new_objects_with_param(int num, P param)
    {
        object_manager_st stObjMan;
        stObjMan.obj_this = new T[num](param);
        if (nullptr != stObjMan.obj_this) {
            //取得函数指针
            stObjMan.delete_ptr = & free_object<T>;
            //保存之
            vec_objects_.push_back(stObjMan);
        }
        return (T*)(stObjMan.obj_this);
    }
};

调用示例如下:

int main(int argc, char* argv[])
{
    //cwSL3D_test_sum();//测试能否成功调用所有接口
    XAutoFreeObject stAutoManager;

    char* strMem = (char*)stAutoManager.malloc_mem(100);

    std::string* pstr = stAutoManager.new_object<std::string> ();

    std::string* pstr2 = nullptr;
    stAutoManager.new_object(&pstr2);
    {
        std::vector<int>* pvec = nullptr;
        stAutoManager.new_object(&pvec);

        std::vector<int>* pvec2 = nullptr;
        stAutoManager.new_objects(&pvec, 2);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/eaglexmw/p/11405424.html

时间: 2024-07-30 00:29:50

C++函数中,两个自动释放内存的动态内存申请类的相关文章

第34条:以“自动释放池块”降低内存峰值

本条要点:(作者总结) Objective-C 对象的生命期取决于其引用计数(参见第29条).在 Objective-C 的引用计数架构中,有一项特性叫做"自动释放池"(autorelease pool).释放对象有两种方式:一种是调用 release 方法,使其保留计数立即递减:另一种是调用 autorelease 方法,将其加入 "自动释放池"中.自动释放池用于存放那些需要稍后某个时刻释放的对象.清空(drain)自动释放池时,系统会向其中的对象发送 relea

动态内存1(动态内存与智能指针)

静态内存用来保存局部 static 对象.类 static 数据成员 以及任何定义在函数之外的变量.栈内存用来存储定义在函数内部的非 static 对象.分配在静态或栈内存中的对象由编译器自动创建和销毁.对于栈对象,仅在其定义的程序块运行时才存在:static 对象在使用之前分配,在程序结束时销毁. 除了静态内存和栈内存,每个程序还拥有一个内存池.这部分内存被称作自由空间或堆.程序用堆来存储动态分配的对象--即,那些在程序运行时分配的对象.动态对象的生存周期由程序来控制,即当动态对象不再使用时,

Java静态内存与动态内存分配的解析

1. 静态内存 静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源. 程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用完毕时,系统会 自动释放所占用的内存空间. 变量的分配与释放,都无须程序员自行考虑. eg:基本类型,数组 2. 动态内存 用户无法确定空间大小,或者空间太大,栈上无法分配时,会采用动态内存分配. 3. 区别 a) 静态内存分配在编译时完成,不占用CPU资源; 动态内存分配在运行时,分配与释放都占用

C之静态内存和动态内存

静态内存: * 自动申请,自动释放* 大小固定,内存空间连续* 从栈上分配的内存叫静态内存 动态内存: * 程序员自己申请 * new/malloc* 大小取决于虚拟内存的大小,内存空间不连续* java中自动回收,C中需要程序员使用free函数手动释放* 从堆上分配的内存叫动态内存 (1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static 变量. (2) 在栈上创建.在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数

堆内存 栈内存 虚拟内存 动态内存管理

从编译器角度来看内存分三种情况: 1 系统初始化时都已经确定好.不会再变动的内存区域,一般指的是全局变量.静态变量数组等. 2 栈上内存:一般指的是函数内部的局部变量等,函数调用时分配内存,调用结束后系统自动释放不用自己考虑回收,效率高.有时候栈需要自己设定,设定不当可造成栈溢出. 3 堆上内存:即用动态分配函数分配的内存属于堆上内存,适合那些有MMU(内存管理).开始不确定需要申请多大内存的场合.注意:利用动态分配内存函数,使用完毕要及时释放内存和将指针清0,否则容易产生野指针和内存泄露.因为

Objective-C(8)内存管理之自动释放池

自动释放池 是一种半自动的内存管理方式 autorealease方法: - (instancetype)autorelease 此方法将对象放到自动释放池中,当自动释放池销毁时,池中的所有对象都会随之销毁. 常见的使用方式: Person *p = [[[Perosn alloc] init] autorelease]; 使用@autoreleasepool关键字来使用自动释放池 其后的{-}相当于自动释放池的生存期 ,如: @autoreleasepool {      Person *p =

C++解析(25):关于动态内存分配、虚函数和继承中强制类型转换的疑问

0.目录 1.动态内存分配 1.1 new和malloc的区别 1.2 delete和free的区别 2.虚函数 2.1 构造函数与析构函数是否可以成为虚函数? 2.2 构造函数与析构函数是否可以发生多态? 3.继承中的强制类型转换 4.小结 1.动态内存分配 1.1 new和malloc的区别 new关键字与malloc函数的区别: new关键字是C++的一部分 malloc是由C库提供的函数 new以具体类型为单位进行内存分配 malloc以字节为单位进行内存分配 new在申请内存空间时可进

黑马程序员-OC学习笔记之autorelease与自动释放池

---------------------- IOS开发.Android培训.期待与您交流! ---------------------- 一.autorelease autorelease与release相似,是OC中的一个对象方法.这两个方法都能把对象的引用计数器减1,但是release是一个精确的减1,对对象的操作只能在release之前进行,如果是在之后,就会出现野指针错误:而autorelease是一个不精确的引用计数器减1,当给对象发送autorelease消息时,对象就会被放到自动

cocos2D-x 3.5 引擎解析之--引用计数(Ref),自动释放池(PoolManager),自动释放池管理器( AutoreleasePool)

#include <CCRef.h> Ref is used for reference count manangement. If a classinherits from Ref. Class Ref 为引用计数类,用来管理对象的引用计数.这样就不会出现还有指针保持指向该对象,当使用该指针操作时,如果指向的对象被销毁就会出现程序异常. class CC_DLL Ref { public: void retain();//增加引用计数一次 void release();//减少引用计数一次,