C++超详细探究new/delete的使用

2022-11-13 11:11:25 探究 详细 delete

内存管理

c++中,一个可执行程序的虚拟地址空间可分为,内核、栈、共享库的内存映射区域、堆、数据区和代码段,具体分布额如下图所示:

内核: 操作系统

栈区: 函数的形参,非静态的局部变量,函数现场保护数据等等,栈是向下增长的。

共享库的内存映射区域 用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信。

堆区: 用于程序运行时动态内存分配,堆是可以上增长的。

数据段: 存储全局数据和静态数据,分为.bss 和.data 。

代码段: 可执行的程序(机器指令)和 常量数据。

C的动态内存管理:

new/delete

在C++中 ,关于动态内存的申请,依靠关键字new来实现,new在有三种用法:

1.new运算符的使用

示例如下:

int n = 10;
int *ipa = new int (10); 
int *ipb = new int [n](10);
int *ipc = new int[n]{1,2,3,4,5,6,7,8};

在这里new主要做了三个操作,

  • 申请一个空间
  • 在申请的空间中构造一个int 的对象,并将该对象返回到空间中
  • 将空间的地址返回

在上述的代码中,我们可以开辟一个空间如 ipa 所示;我们也可以开辟一组空间如ipb所示;我们也可以开辟一组空间的同时给所有或者部分元素给定初始值如ipc所示。

当然,动态内存的开辟后,需要我们去手动去释放它,在C++ 中,我们通过delete来释放内存,如下所示

delete ipa;
delete[]ipb;
delete[]ipc;

如上代码所示,当我们开辟一个空间时,我们可以直接通过其地址释放,当我们申请一组空间时,我们需要加上**[]**,需要告诉编译器,我们要释放一组内存。

注: 当我们释放一组内存时,我们不需要在[]里面写入需要释放的动态内存的数目,原因是当我们通过new去申请一组动态内存时,编译器会自动开辟空间去保存new开辟的空间的数目大小,当我们使用delete 来释放空间时,编译器会自动去访问这个空间来查看开辟的内存大小数目。

2.new的函数方法的使用

new当作函数使用时,其功能和malloc及其相似,唯一不同的地方在与 当申请内存失败时,malloc会返回NULL,因此,我们在每次使用malloc时候必须对指针进行判空;但是new申请内存失败后是抛出异常,所以需要捕获异常处理程序;

示例如下:

int n = 10;
int *ipa = (int*)::operator new(sizeof(int));
// 			     (int*)malloc(sizeof(int));
int *ipb = (int*)::operator new(sizeof(int)*n);
// 				  (int*)malloc(sizeof(int)*n);

当然,我们也需要delete去释放其空间

 delete(ipa);
 delete(ipb);

3.定位new

定位new的用法主要是,它不会去自己开辟空间,而是一块已知的内存上分配给一个对象,但是内存上的数据不会被覆盖或者改写,其代码示例如下:

int n = 10;
int* ipa = (int*)malloc(sizeof(int));
int* ipb = (int*)::operator new(sizeof(int) * n);
new(ipa) int(20);
new(ipb) int[]{ 1,2,3,4,5,6,7,8,9 };

并且 ,通过定位new的方法去把已经申请的存在的内存分配的方法,它可以去分配堆里面的内存,也可以去分配栈里面的内存;定位new的方法也可以将原本申请为int类型的内存看成char/double来显示。

注: 关于C++的内置类型 int/double/char 等等 ,并不是编译器将其划分,而是使用者自身,当我们把数据按照4个字节当一个整体来看待,那么其就是整型,若是按照一个字节为一个单位,那就是char类型;若是8个字节看成一个单位,那就是double类型。而数据在内存存储的值并不会发生任何改变。

new/delete/malloc/free区别

1、new/delete 是C++中的运算符。 malloc / free 是函数。

2、 malloc申请内存空间时,手动计算所需大小,new只需类型名,自动计算大小;

3、 malloc申请的内存空间不会初始化,new可以初始化;

4、 malloc的返回值为void*, 接收时必须强转,new不需要;

5、 malloc申请内存空间失败时,返回的是NULL,使用时必须判空;

new申请内存空间失败时抛出异常,所以要有捕获异常处理程序;

到此这篇关于C++超详细探究new/delete的使用的文章就介绍到这了,更多相关C++ new/delete内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章