【C++】动态内存管理

数据的类型:

对于程序而言,数据的类型大概有以下几种:局部数据、静态数据和全局数据、常量数据、动态申请数据。这些数据别有特点,服务于实际需求。
而程序在运行时,这些数据由于不同的特性和用途,分别存储在内存的不同位置中。

虚拟进程地址空间:

把内存大致进行划分,可以得到一份数据存储分布图。

在这里插入图片描述

new && delete

在C语言中有配套的malloc/realloc/calloc 和 free 的动态申请/销毁空间函数。
在C++中同样也可以用C语言的方法,但其另有一套 new 和 delete 关键字的玩法,且比上述方法更加简便。

//C
int* i = (int*)malloc(sizof(int));
free(i);

//CPP
int* j = new int;
delete j;

//对于数组而言
//C
int* arr1 = (int*)(sizof(int) * 10);
free(arr1);

//CPP
int* arr2 = new int[10];
delete[] arr2;  

这两种方法各成一派,混合使用很可能会出现错误。

初始化:

注意,new && delete 这一套方法是不会对开辟的动态内存空间进行初始化。

//对单个数据进行初始化
int* k = new int(0);

//对数组进行初始化
int* arr3 = new int[10]{1,2,3};//其余被初始化为0

//如果是对类的多个对象进行初始化,那么除了默认构造函数是全缺省参数外,其它情况下都是要将初始化写全

A* arr4 = new A[3]{A(2,2), A(1,1), A(4,3)};
//这里也体现了匿名函数的特点

这种初始化的方法比起C语言中的方法而言十分方便。

使用细节:

这两套方案在针对内置类型进行使用时,除了在用法上的差别,其它并无太大不同。
但对于自定义类型,new会调用构造函数,delete会调用析构函数
在这里插入图片描述

两套方法的区别:

从底层的角度上看,由于C++自定义类型的广泛使用,传统的malloc/free方法对于开辟空间并且初始化显得比较麻烦,malloc/free方法只是申请了空间,并未进行初始化。
new/delete方法是先用operate new方法开辟空间,再调用构造函数对资源进行初始化。在销毁时,是先用析构函数对资源进行销毁,再使用operate delete方法对空间进行释放。

浅显一点地看,使用malloc申请空间时,需要对空间大小进行计算(使用sizeof操作符可以很大程度上减少计算量),需要进行强转类型(一般由对应类型指针来“接收”),如果失败了会返回NULL,判断时要注意。而使用new申请空间时,上面的过程已经集成好了,相当于流水线,只是在申请失败时会抛出异常,处理时要有捕捉异常的代码。

cout小知识:

cout 具有自动识别功能,本质是函数重载,其可以打印不同类型的数据,但以下涉及指针的比较特殊。

char* p1 = new char[1024*1024];
cout << p1 << endl;//cout会将char*识别成字符串,直到遇到\0才停止,因此这很可能会出现乱码

char* p1 = new char[1024*1024];
cout << (void*)p1 << endl;//对p1进行强转就会只打印开辟空间的地址

内存泄漏:

内存泄漏不是物理意义上的内存丢失,而是由于设计失误,应用程序未能将不再使用的内存完整地释放返回给操作系统。

普通程序的内存泄漏问题不大,哪怕崩溃了只要程序一结束内存就回来了。
但是对应像后台服务那样长期运行的程序而言,内存泄漏造成的影响是持久且明显的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值