亲宝软件园·资讯

展开

C++ new/delete

编程小程 人气:0

内存管理

在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主要做了三个操作,

在上述的代码中,我们可以开辟一个空间如 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申请内存空间失败时抛出异常,所以要有捕获异常处理程序;

加载全部内容

相关教程
猜你喜欢
用户评论