C++动态内存管理
来源:互联网 发布:西安软件新城附近楼盘 编辑:程序博客网 时间:2024/06/14 17:57
要研究C++动态内存管理,
我们的先了解一下C语言中的malloc/calloc/realloc/free.
void* malloc(size_t Size);
malloc在动态存储区分配一块空间为size字节大小的连续区域;没有对其初始化
void* calloc(size_t count,size_t size);
calloc在动态存储区里边分配一块长度为count,size字节大小的空间。并把这块内存初始化为0;
void* realloc(void* Memory,size_t Newsize);
realloc用于修改一个原先已经分配好的内存空间,如果要开辟的空间大于原来的空间,就在原来的空间
后边看还有没有足够的空间,如果有就直接在后边在开辟一点空间。如果不够就重新找一块连续的区域。
增加的空间不进行初始化。
如果Memory等于NULL,那么它和malloc作用相同。
例子:
int main(){ int *p1 = (int*)malloc(sizeof(int)); //开辟一个字节的空间 int* p2 = (int*)calloc(3, sizeof(int));//开辟3个字节的空间 int *p3 = (int*)realloc(p2, 5 * sizeof(int)); //在p2的基础上扩容开辟5个字节的空间 free(p1); free(p3); return 0;}
C++动态内存管理
C++通过new/delete来管理内存
new/delete管理对象
new []/delete[] 管理对象数组。
例子:
int main(){ int *p1 = new int; //开辟一个字节大小的空间 int* p2 = new int(6);//开辟一个字节大小的空间并初始化为6 int* p3 = new int[6];//开辟6个字节大小的空间 delete p1; delete p2; delete[]p3; return 0;}
【malloc/free和new/delete的区别与联系】
1. 它们都是动态管理内存的入口
2. malloc/free是C/C++的库函数,new/delete是C++的操作符。
3. malloc/free只是动态的开辟空间释放空间,而new/delete除了会分配空间还会调用构造函数
和析构函数进行初始化和清理工作。
4. malloc/free需要手动的计算size还有返回时void*,new/delete会自动计算空间的大小,
返回对应类型的指针
class AA{public: AA() :_a(NULL) { cout << "AA()" << endl; _a = new int(0); } ~AA() { cout << "~AA()" << endl; if (_a) { delete _a; _a = NULL; } }private: int *_a;};void TestAA(){ AA* tmp = new AA[10]; cout << "多开辟了那四个字节存放什么?" << *((int*)tmp - 1) << endl; delete[]tmp;}
在这里猜一下会开辟多大的空间?
为什么会多开辟4个字节大小的空间。
我们猜想可能是存放的析构次数。
然后我们用这个表达式*((int*)tmp - 1)打印出那块空间
在这里new[N]做了两件事:
1. 调用operator new[] 开辟空间
2. 调用了N次构造函数进行初始化。
delete[]也做了两件事:
1. 调用了N次析构函数进行清理工作
2. 调用了operator delete []释放空间。
定位new表达式
作用:是在已分配的原始空间上调用构造函数进行初始化一个对象。
new (place_address)type
new (place_address)type(initializer-list)
place_address必须是指针。 type类型
我们也可以用malloc和free模拟实现new/delete
void TestAA(){ AA* tmp = new AA[10]; cout << "多开辟了那四个字节存放什么?" << *((int*)tmp - 1) << endl; delete[]tmp; AA* tmp = (AA*)malloc(10 * sizeof(AA));//模拟上边 for (size_t i = 0; i < 10; i++) { new (tmp + i)AA; } for (size_t i = 0; i < 10; i++) { tmp[i].~AA(); } free(tmp);}
我们还可以模拟它的那四个字节存放析构次数的功能
class AA{public: AA() :_a(NULL) { cout << "AA()" << endl; _a = new int(0); } ~AA() { cout << "~AA()" << endl; if (_a) { delete _a; _a = NULL; } }private: int *_a;};AA* New(size_t N){ AA* tmp = (AA*)malloc(N*sizeof(AA)+sizeof(int));//多开辟4的字节的空间 *((int*)tmp) = N; //在那四个字节里存放析构次数 tmp = (AA*)((int*)tmp + 1);//把空间向后置四个字节大的大小 for (size_t i = 0; i < N; i++) { new (tmp + i)AA;//调用new的定位表达式初始化 } return tmp;}void Del(AA* pt){ int N = *((int*)pt - 1); //算出空间的前4个字节 AA* p = (AA*)((int*)pt - 1); //记录malloc起初的位置 for (size_t i = 0; i < N; ++i) { pt[i].~AA(); //调用析构函数清理工作 } free(p);}void TestAA(){ AA* tmp = New(10); cout << "多开辟了那四个字节存放什么?" << *((int*)tmp - 1) << endl; Del(tmp);}
深度剖析new/delete & new[] /delete []
- 【C++】动态内存管理
- 【C++】动态内存管理
- 【C++】动态内存管理
- C语言动态内存管理
- c的动态内存管理
- C语言动态内存管理
- C语言动态内存管理
- C/C++动态内存管理
- C语言动态内存管理
- 【C++】C++动态内存管理
- C/C++动态内存管理
- c的动态内存管理
- C/C++动态内存管理
- c/c++动态内存管理
- C/C++动态内存管理
- C/C++动态内存管理
- C/C++动态内存管理
- C/C++动态内存管理
- C语言攻略
- grub-efi-amd64-signed安装失败
- java 多线程编程
- bat实现给多个设备安装APK
- 详解JavaScript ES6中export import与export default的用法和区别
- C++动态内存管理
- strtok、strtok_s、strtok_r 字符串分割函数
- 我不管,我就是想学会01背包嘛~~
- A
- MySQL数据类型和常用字段属性总结
- Problem
- layer 之子父窗口传值
- spring @postConstruct init-method constructor和afterSetProperties() 执行顺序
- 简析Java序列化