一、C/C++内存分布
在我们写代码时,会定义很多的变量,有静态的、全局的、局部的等等,但是这些变量在内存中是分别存放在不同的位置上;
二、C语言内存管理
在C语言中,我们是通过malloc/calloc/realloc来申请动态内存的,通过free来释放内存的;
malloc:申请一块空间,对里面的内容不做任何处理;
calloc:申请一块空间,并对立面的值全部初始化为0;
realloc:对空间进行扩容,先申请一片更大的空间,再将原有空间的信息拷贝过来,最后再释放原有空间;
free:对malloc/calloc/realloc所申请的空间进行释放,如不释放,则会造成内存泄漏,危害极大;
三、C++内存管理
(一)内存管理函数——new、delete
1、动态申请内存——new
C++中通常使用new来申请内存,原因是:用malloc申请空间,不会进行初始化,这样自定义类型就不能够进行初始化,所以使用new动态申请空间;
(1)申请方式
类型 类型名 = new 类型;
例如:
class Data
{
private:
int _year = 0;
int _month = 0;
int _day = 0;
public:
Data(){}
Data(int year = 0, int month = 0, int day = 0){}
~Data(){}
};
int main()
{
//内置类型申请
int* p = new int;
int* pa = new int[10]; //申请连续空间
int* pb = new int(20); //申请内容为20的空间(申请+初始化)
//自定义类型申请
Data pd = new Data; //自动调用默认构造完成初始化
Data pd2 = new Data(2020, 10, 24);
Data pd3 = new Data[10]; //创建自定义类型数组,只能调用默认构造,不能加()赋值;
return 0;
}
(2)底层实现原理
operator new是一个系统提供的全局函数,new是对operator new的一个封装,实际上在使用new申请时,会调用operator new;
而operator new函数内部会用到malloc,实际上是malloc + 异常机制;
所以在调用new对自定义类型申请空间时,底层上都是调用operator new函数申请空间,再调用构造函数给空间赋值;
2、释放内存——delete
C++中与new配套的释放内存的函数就是delete,同样的,如果使用free来释放自定义类型的空间的话,并不会调用自定义类型的析构函数,也就是说不会释放自定义类型里的资源,所以使用delete函数进行资源的释放;
(1)释放方式
delete 变量名; //释放一个空间
delete[] 变量名; //释放连续空间
接上上面的例子:
class Data
{
private:
int _year = 0;
int _month = 0;
int _day = 0;
public:
Data(){}
Data(int year = 0, int month = 0, int day = 0){}
~Data(){}
};
int main()
{
//内置类型申请
int* p = new int;
int* pa = new int[10]; //申请连续空间
int* pb = new int(20); //申请内容为20的空间(申请+初始化)
//自定义类型申请
Data pd = new Data; //自动调用默认构造完成初始化
Data pd2 = new Data(2020, 10, 24);
Data pd3 = new Data[10]; //创建自定义类型数组,只能调用默认构造,不能加()赋值;
//释放内置类型
delete p;
delete[] pa;
delete pb;
//释放自定义类型
delete pd;
delete pd2;
delete[] pd3;
return 0;
}
(2)底层实现原理
operator delete与operator new函数一样,都是操作系统提供的全局函数,delete是对其的一个封装;
operator delete内部就是通过free函数来完成空间释放的,这里如果失败不会抛异常;
所以通过delete释放自定义类型空间时,都是先调用析构函数将自定义类型内部的资源先释放掉,再调用operator delete函数将空间释放;
四、内存泄漏
1、什么是内存泄漏
内存泄漏是因为疏忽或错误造成程序未能释放已经不再使用内存的情况。内存泄漏并不是指内存在物理层面上的消失,而是指某段内存被分配出去后,因为一些错误而不受控制;
2、内存泄漏的危害
内存泄漏会导致系统可用内存越来越少,最终死机;
3、内存泄漏种类
堆内存泄漏、系统内存泄漏;
4、如何防范内存泄漏
(1)养成良好的代码规范,即申请一个内存后要记得释放;
(2)采用RALL思想或智能指针来管理资源;
(3)使用内存检测工具:常见的有valgrind;