C++动态内存管理核心知识点总结
来源:互联网 发布:网络安全工程师职责 编辑:程序博客网 时间:2024/05/21 09:16
动态内存管理核心:
首先,我们来重载一下operator new ();进行预处理,给我们打印一些有用的 信息,比如:当前定位的行号,开辟空间的大小(方便我们对于内存泄漏的检查)
#include<iostream>using namespace std;class Test{public: Test() { cout << "Test()" << endl; } ~Test() { cout << "Test()" << endl; }private: int _data;};void* operator new(size_t size, const char*fileName, const char*funcName, int lineNo){ cout << fileName << ":" << funcName << "--" << lineNo << endl; cout << size <<endl; return malloc(size);}#if _DEBUG#define new new(__FILE__,__FUNCDNAME__,__LINE__)#endif//此时需要对operator new 进行重载,系统中没有合适的operator newvoid FunTest(){ Test*p = new Test;}int main(){ FunTest(); return 0;}
效果如图所示:
下来,我们对new/delete 和new[]和delete[]进行仿写,了解一下底层实现
#include<iostream>using namespace std;class Test{public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; }private: int _data;};Test* New(size_t size){ Test* p = (Test*)malloc(size); if (NULL == p) { return p; } //执行构造函数 new(p)Test;//定位new 表达式执行构造函数 return p;}//delete ->析构函数-》释放空间void Delete(Test*p){ //要调用函数,那就要对调用它的指针进行判空处理 if (p) { p->~Test(); free(p); }}//new[]-->malloc//多开辟四个字节来保存数组数量Test* NewArray(size_t count){ int *p = (int *)malloc(count + 4); //malloc之后就要对返回值进行判空处理 if (p == NULL) { //return p;//直接返回p与声明类型不一致 return NULL; } *p = count; //p = (Test*)(p + 1);->类型不匹配,我们重新定义一个指针 Test* pt = (Test*)(p + 1); for (size_t idx = 0; idx < count; ++idx) { //使用定位new表达式 new(pt + idx)Test; } return pt;//返回起始构造函数的位置}//delete[]void DeleteArray(Test*p){ //分情况-》空,不空 if (p == NULL) { return; } int count = *((int *)p - 1); //从后往前析构 for (int idx = count - 1; idx >= 0; --idx) { (p + idx)->~Test(); } free((int *)p - 1);//从开辟的起始位置进行释放}void FunTest1(){ Test*p = New(sizeof(Test)); Delete(p); Test*p1 = NewArray(10); DeleteArray(p1);}int main(){ FunTest1(); //FunTest(); return 0;}
接下来,我们再来看一下为什么一定要匹配使用?
#include<iostream>using namespace std;class Date{private: int _year; int _month; int _day;};void FunTest1(){ int *p1 = new int[5]; int *p2 = new int[5]; int *p3 = new int(2); int* p4 = new int(3); delete p1; delete[]p2;// delete p3; delete[]p4;//因为int 为内置类型,所以析构时无需知道数组的大小}void FunTest2(){ Date* p1 = new Date(); Date*p2 = new Date(); Date*p3 = new Date[5]; Date*p4 = new Date[5]; delete p1; delete[] p2; delete p3; delete[] p4;}int main(){ FunTest1(); FunTest2(); return 0;}
程序执行完,并没有发生错误。
因为对于内置类型和没有显示给出析构函数的类,系统可以直接释放。
那我们显示给出析构函数看一下程序执行结果。从上面的导图饿哦们可以大致了解到,对于非内置类型或无自定义析构函数的类类型来说,析构一段数组空间时,需要知道数组的大小。
#include<iostream>using namespace std;class Date{public: /*Date(int year = 0, int month = 0, int days = 0) :_year(year) , _month(month) , _day(days) { }*/ ~Date() { }private: int _year; int _month; int _day;};void FunTest1(){ int *p1 = new int[5]; int *p2 = new int[5]; int *p3 = new int(2); int* p4 = new int(3); delete p1; delete[]p2;// delete p3; delete[]p4;//因为int 为内置类型,所以析构时无需知道数组的大小}void FunTest2(){ Date* p1 = new Date(); Date*p2 = new Date(); Date*p3 = new Date[5]; Date*p4 = new Date[5]; delete p1; delete[] p2; delete p3; delete[] p4;}int main(){ FunTest1(); FunTest2(); return 0;}
此时。程序就会发生崩溃,这就是我们为什么要配套使用new/delete 与new[]/delete[] 的原因了。
new[]的开辟四个字节空间图:
注:该图来自于:http://blog.csdn.net/hazir/article/details/21413833
1 0
- C++动态内存管理核心知识点总结
- Glibc 内存管理知识点总结
- Glibc 内存管理知识点总结
- 【C】《C专家编程》核心知识点总结
- 【C++】动态内存管理
- 【C++】动态内存管理
- 【C++】动态内存管理
- MMU内存管理单元相关知识点总结
- C语言动态内存管理
- c的动态内存管理
- C语言动态内存管理
- C语言动态内存管理
- C/C++动态内存管理
- C语言动态内存管理
- 【C++】C++动态内存管理
- C/C++动态内存管理
- c的动态内存管理
- C/C++动态内存管理
- (邻接表构图-网络寻路题解
- 135. Candy
- 数据结构—树与二叉树篇I
- Hibernate 关联关系
- 136. Single Number
- C++动态内存管理核心知识点总结
- Mybatis Generator配置说明
- 分词统计(四)唐宋元诗人吟诗作词的时候,最偏爱哪些词语呢?(附上AI写的1000句诗!)
- Git忽略规则及.gitignore规则不生效的解决办法
- 09-jQuery和ajax-2
- oj_64 新年组队
- 炫酷安卓垃圾回收动画
- 关于公司层次的思考
- java动态代理与静态代理