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

 更新时间:2022年07月01日 10:46:49   作者:编程小程  
这篇文章主要介绍了C++中new与deleted关键字的使用,new在动态内存中为对象分配空间并返回一个指向该对象的指针;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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • pybind11: C++ 工程提供 Python 接口的实例代码

    pybind11: C++ 工程提供 Python 接口的实例代码

    这篇文章主要介绍了pybind11: C++ 工程如何提供 Python 接口,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • C++ 命名空间 using声明使用示例详解

    C++ 命名空间 using声明使用示例详解

    这篇文章主要为大家介绍了C++ 命名空间 using声明使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • C++ OpenCV实战之图像透视矫正

    C++ OpenCV实战之图像透视矫正

    这篇文章主要介绍了通过C++ OpenCV实现图像的透视矫正,文中的示例代码讲解详细,对我们的学习或工作有一定的参考价值,感兴趣的可以了解一下
    2022-01-01
  • Qt之QTimer使用及技巧小结

    Qt之QTimer使用及技巧小结

    QTimer是Qt中的定时器类,用于执行定时操作,如在一段时间间隔后触发某个槽函数或执行特定的代码,下面就来介绍一下Qt之QTimer使用及技巧小结,感兴趣的可以了解一下
    2023-10-10
  • C++卸载程序功能示例

    C++卸载程序功能示例

    用C++写一个自己的卸载程序来完成程序的卸载工作,同时运行后要删除卸载程序本身,并删除卸载程序所在的文件夹
    2013-11-11
  • 深入解析设计模式中的适配器模式在C++中的运用

    深入解析设计模式中的适配器模式在C++中的运用

    这篇文章主要介绍了设计模式中的适配器模式在C++中的运用,通常适配器模式可以细分为类适配器和对象适配器两种情况,需要的朋友可以参考下
    2016-03-03
  • c语言实现php的trim标签

    c语言实现php的trim标签

    本文给大家介绍的是使用C语言实现php的trim标签功能的代码,非常的实用,其主要作用是清除字符串开头结尾除空白,有需要的小伙伴可以参考下。
    2016-01-01
  • C++ 构造函数中使用new时注意事项

    C++ 构造函数中使用new时注意事项

    本文主要介绍了C++ 构造函数中使用new时注意事项。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • c语言main函数使用及其参数介绍

    c语言main函数使用及其参数介绍

    这篇文章主要介绍了c语言main函数使用及其参数介绍,需要的朋友可以参考下
    2014-04-04
  • C++实现多人聊天室

    C++实现多人聊天室

    这篇文章主要为大家详细介绍了C++实现多人聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06

最新评论