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(); 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, );
}
return ;
}
C++函数中,两个自动释放内存的动态内存申请类的更多相关文章
- C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)
C++语言定义了两个运算符来分配和释放动态内存:运算符new分配内存,运算符delete释放new分配的内存. 运算符new和delete 使用new动态分配和初始化对象 在自由空间分配的内存是无名的 ...
- 【STM32H7教程】第27章 STM32H7的TCM,SRAM等五块内存的动态内存分配实现
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第27章 STM32H7的TCM,SRAM等五块内 ...
- Java静态内存与动态内存分配的解析
1. 静态内存 静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源. 程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用 ...
- C之静态内存和动态内存
静态内存: * 自动申请,自动释放* 大小固定,内存空间连续* 从栈上分配的内存叫静态内存 动态内存: * 程序员自己申请 * new/malloc* 大小取决于虚拟内存的大小,内存空间不连续* ja ...
- SDUT OJ 字典树 AND 静态内存与动态内存
字典树 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 遇到单词不认识怎么办? 查字典 ...
- 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体
1.字符串输出输入函数 读入字符串的方法: 1) scanf 特点:不能接收空格 2) gets 特点:可以接受含有空格的字符串 ,不安全 3) fgets(); 特点:可以帮我们自动根据数组的长度截 ...
- 深入理解C++中的new/delete和malloc/free动态内存管理
malloc/free和new/delete的区别 malloc/free是C/C++标准库的函数:new/delete是C++操作符. malloc/free只是动态分配内存空间/释放空间:new/ ...
- C++ Primer 5th 第12章 动态内存
练习12.1:在此代码的结尾,b1 和 b2 各包含多少个元素? StrBlob b1; { StrBlob b2 = {"a", "an", "th ...
- iOS内存管理系列之二:自动释放与便捷方法
有时候一个所有者创建一个对象后,会立刻将该对象的指针传递给其它所有者.这时,这个创建者不希望再拥有这个对象,但如果立刻给它发送一个release消息会导致这个对象被立刻释放掉——这样其它所有者还没有来 ...
随机推荐
- [leetcode] 67. Add Binary (easy)
原题链接 思路: 用一个数保存进制,从后往前不断pop出两个数字和进制数相加,放入返回值中. var addBinary = function(a, b) { var arrA = a.split(' ...
- [HDOJ] 2026.Max Sum
2026.Max Sum (c++) Problem Description Consider the aggregate An= { 1, 2, -, n }. For example, A1={1 ...
- 钉钉E应用(小程序)之日历
唠叨几句:其实钉钉E应用的编写类似支付宝小程序(毕竟是阿里爸爸下的产业),而支付宝小程序又是chao xi 微信小程序(只不过人家是wxml / wxss ,他是 axml / acss罢了),这三者 ...
- get 请求和post请求的具体区别
get请求是向服务器索要数据,post请求是向服务器传送数据 的,浏览器限制了get的传送量,post可以大量的把数据传给 服务器,一般情况下get请求,请求体是空的,请求只发一次 ,如果是post请 ...
- C#编程.循环的中断
1 循环的中断 break-立即终止循环(继续执行循环后面的第一行代码) continue-立即终止当前的循环(继续执行下一次循环) goto-可以跳出循环,到已标记好的位置上(如果希望代码易于阅读和 ...
- TreeMap 还能排序?分析下源码就明白了
Java 中的 Map 是一种键值对映射,又被称为符号表或字典的数据结构,通常使用哈希表来实现,但也可使用二叉查找树.红黑树实现. HashMap 基于哈希表,但迭代时不是插入顺序 LinkedHas ...
- linux初学者-系统日志(一)
linux初学者-系统日志(一) 系统日志可以记录系统的运行状态,如果运行故障,会说明错误的位置.所以对系统日志的了解和学习是非常有必要的. 1.系统日志的默认分类 系统日志会默认记录在以下地址中,不 ...
- 7kyu (难度系数kyu阶段数值越大难度越低) 数组分组及求和
几个人排成一排,分成两队.第一个人进入一队,第二个人进入第二队,第三个人进入第一队,以此类推. 给定一个正整数的数组(人的权重),返回两个整数的新数组/元组,其中第一个是第1组的总重量,第二个是第2组 ...
- 【Android】Fresco 初次使用遇到的坑
初次使用开源框架 Fresco,结果遇到了坑,被虐了半下午--暂且记下. 下面的错误 android.view.InflateException: Binary XML file line #** 报 ...
- .NET Core on K8S学习实践系列文章索引(Draft版)
一.关于这个系列 自从去年(2018年)底离开工作了3年的M公司加入X公司之后,开始了ASP.NET Core的实践,包括微服务架构与容器化等等.我们的实践是渐进的,当我们的微服务数量到了一定值时,发 ...