C++内存管理
1.C&&C++内存分布
程序内存区域划分:
(1)内核空间(用户代码不可读写)
(2)栈(向下生长):非静态局部变量、函数参数、返回值
(3)内存映射段(文件映射、动态库、匿名映射):高效的I/O映射方式,用于装载一个共享的动态内存库。用户可以用系统接口创建共享内存,进行进程间通信
(4)堆(向上增长):运行时动态内存分配
(5)数据段(全局数据、静态数据):存储全局数据和静态数据
(6)代码段:可执行代码/只读常量
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
//全局数据和静态数据存储在数据段
int globalVar = 1;//全局数据
static int staticGlobalVar = 1;//静态数据
int main()
{
static int staticVar = 1;//静态数据(数据段)
//栈区(非静态局部变量/函数参数/返回值)
int localVar = 1;//栈区
int num1[10] = { 1,2,3,4 };//栈区
char char2[] = "abcd";//代码段(可执行代码和只读常量)
char* pchar3 = "abcd";//代码段
int* ptr1 = (int*)malloc(sizeof(int) * 4);//堆(运行时动态分配)
int* ptr2 = (int*)calloc(4, sizeof(int));//堆
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);//堆
cout << sizeof(num1) << endl;//40
cout << sizeof(char2) << endl;//5(有\0)
cout << strlen(char2) << endl;//4
cout << sizeof(pchar3) << endl;//8
cout << strlen(pchar3) << end;//4
cout << sizeof(ptr1) << endl;//8
free(ptr1);
free(ptr3);
return 0;
}
2.C/C++动态内存管理方式
(1)C语言动态内存管理(malloc/calloc/realloc/free)
(2)C++内存管理方式(new/delete)
注:new会调用构造函数,delete会调用析构函数;malloc/free不会。
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
int* ptr1 = new int;//动态申请一个int类型的空间
int* ptr2 = new int(10);//动态申请一个int类型的空间并初始化为10
int* ptr3 = new int[3];//动态申请3个int类型的空间
delete ptr1;
delete ptr2;
delete[] ptr3;
return 0;
}
3.operator new 和operator delete 函数
-
new和delete是用户进行动态内存申请和释放的操作符。
-
operator new和operator delete是实际上是通过malloc和free来申请和释放空间的。
-
operator new和operator delete是系统提供的全局函数,new和delete在底层调用二者来申请和释放空间。
4.new和delete的实现原理
(1)内置类型
new和malloc,delete和free基本类似,但是: -
new/delete申请释放单个元素空间,new[]/delete[]申请释放连续空间。
-
new申请失败会抛出异常,malloc会返回NULL。
(2)自定义类型 -
new:调用operator new申请空间;在申请空间上执行构造函数,完成对象构造。
-
delete:在空间上执行析构函数,完成资源的清理工作;调用operator delete释放空间
-
new[N]:调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请;在申请的空间上执行N此构造函数。
-
delete[]:在释放的对象空间上执行N次析构函数,完成对N个对象中资源的清理;调用operator delete[]释放空间,实际上在operator delete[]中调用operator delete来释放空间。
5.malloc/free和new/delate的区别与联系
(1)共同点:从堆上申请空间,需要手动释放
(2)不同点:
6.内存泄漏
因为疏忽或错误造成程序未能释放已经不再使用内存的情况。应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因此造成对内存的浪费。
危害:长期运行的程序出现内存泄漏,会导致响应越来越慢,最终卡死。
原因:内存申请忘记释放;异常安全问题,即释放执行前有异常抛出导致未被释放。
避免:发生前,使用智能指针;发生后,使用泄漏检测工具。