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

目录
  • 内存管理
  • new/delete
    • 1.new运算符的使用
    • 2.new的函数方法的使用
    • 3.定位new
  • new/delete/malloc/free区别

内存管理

在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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c++动态内存管理详解(new/delete)

    目录 前言 用法上 对内置类型 对自定义类型 new/delete底层原理 重载类的专属operatornew和operatordelete 定位new new/delete与malloc/free区别总结 内存泄漏 总结 前言 想必大家对c语言的动态内存分配并不陌生,忘了的小伙伴也可以看看我的这篇文章C语言动态内存分配 c语言的动态内存分配由于有些地方用起来比较麻烦同时检查错误的机制不适合c++,因此c++引入new/delete操作符进行内存管理,下面我们来深入探讨c++为什么要引入new/

  • C++使用new和delete进行动态内存分配与数组封装

    目录 1.使用new申请内存 2.使用delete释放内存 3.使用new申请内存时的初始值 4.使用new和delete申请和释放数组空间 5.用类封装new申请和释放的数组空间 6.使用new申请多维数组 1.使用new申请内存 在某些情况下,程序只有在运行期间才能确定所需内存大小,此时应该使用new申请内存.申请成功的情况下会返回首地址,通过指向首地址的指针可以访问申请的内存,使用new申请内存的的语法如下: new 数据类型(初始化参数列表); 下面的例子定义了Duck类型的指针,并通过

  • 最新C/C++中的new和delete的实现过程小结

    目录 new delete new[] delete[] 下面是<C++ Primer 5th>中P726 对 new 和 delete 过程的解释: 当我们使用一条new表达式时,实际上执行了三步操作: new表达式调用一个名为 operator new (或者 operator new[] )的标准库函数.该函数分配一块足够大的.原始的.未命名的内存空间以便存储特定类型的对象(或者对象数组). 编译器运行相应的构造函数以构造这些对象,并为其传入初始值. 对象被分配了空间并构造完成,返回一个

  • C++ 动态内存分配详解(new/new[]和delete/delete[])

    一.为什么需要动态内存分配? 在C++程序中,所有内存需求都是在程序执行之前通过定义所需的变量来确定的. 但是可能存在程序的内存需求只能在运行时确定的情况. 例如,当需要的内存取决于用户输入. 在这些情况下,程序需要动态分配内存,C ++语言将运算符new和delete合成在一起. (1)特点 1.C++中通过new关键字进行动态内存申请 2.C++中的动态内存分配是基于类型进行的 3.delete关键字用于内存释放 (2)语法 ①变量申请: Type* pointer = new Type;

  • C++的new和delete详解

    目录 1.new和delete的内部实现 2.placement技术 3.new和delete运算符重载 4.对象的自动删除技术 1.new和delete的内部实现 C++中如果要在堆内存中创建和销毁对象需要借助关键字new和delete来完成.比如下面的代码 class CA { public: CA()m_a(0){} CA(int a):m_a(a){} virtual void foo(){ cout<<m_a<<endl;} int m_a; }; void main()

  • C++深入讲解new与deleted关键字的使用

    目录 可执行程序的虚拟地址空间 1.new的运算符用法(关键字) 2.new的函数用法 3.定位new 4.new创建对象 5.delete 6.对于内置类型new/delete/malloc/free可以混用 7.使用注意事项 可执行程序的虚拟地址空间 内核:存放操作系统 栈区:函数的形参,非静态的局部变量,函数现场 保护数据等等,栈是向下增长的. 共享库的内存映射区域:用于装载一个共享的动态内存库.用户可使用系统接口创建共享内存,做进程间通信. 堆区:用于程序运行时动态内存分配,堆是可以上增

  •  C++ new 和 delete 关键字详解

    目录 前言 new 和 delete 的使用 new delete 为数组分配内存和释放内存 malloc 和 new delete 和 delete[] 前言 最早接触到new这个关键字,是在 Java 中,然后 ES6 之后的 js 中也提供了 new 这个关键字,在 java 和 js 这两门语言中,使用 new 关键词可以实例化类的对象.语义是相似的,但是其背后还是有些差异的,js 的 new 和 class 可能是一些语法糖. 那么有了这些对 new 这个关键字用法的了解,我们今天来看

  • 深入理解C++中的new和delete并实现对象池

    深入理解new和delete new和delete称作运算符 我们转反汇编看看 这2个运算符本质也是相应的运算符的重载的调用 malloc和new的区别? 1.malloc按字节开辟内存的:new开辟内存时需要指定类型 new int[10] 所以malloc开辟内存返回的都是void* 而new相当于运算符的重载函数 operator new ->返回值自动转成指定的类指针 int* 2.malloc只负责开辟空间,new不仅仅有malloc的功能,可以进行数据的初始化 new int(20)

  • 一篇文章了解c++中的new和delete

    目录 new expression delete expression new[]和new() new[]和delete[] new的内存分布 placement new new失败处理 捕捉异常 禁用new的异常 new-handler 重载 重载全局的::operator new 重载局部的Foo::operator new 重载placement new 总结 new expression new一个类型,会创建一个该类型的内存,然后调用构造函数,最后返回该内存的指针 注意:该操作是原子性

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

    目录 内存管理 new/delete 1.new运算符的使用 2.new的函数方法的使用 3.定位new new/delete/malloc/free区别 内存管理 在C++中,一个可执行程序的虚拟地址空间可分为,内核.栈.共享库的内存映射区域.堆.数据区和代码段,具体分布额如下图所示: 内核: 操作系统 栈区: 函数的形参,非静态的局部变量,函数现场保护数据等等,栈是向下增长的. 共享库的内存映射区域 用于装载一个共享的动态内存库.用户可使用系统接口创建共享内存,做进程间通信. 堆区: 用于程

  • Spring Boot 员工管理系统超详细教程(源码分享)

    员工管理系统 1.准备工作 资料下载 内含源码 + 笔记 + web素材 源码下载地址: http://xiazai.jb51.net/202105/yuanma/javaguanli_jb51.rar 笔记 素材 源码 1.1.导入资源 将文件夹中的静态资源导入idea中 位置如下 1.2.编写pojo层 员工表 //员工表 @Data @NoArgsConstructor public class Employee { private Integer id; private String l

  • 超详细的Intellij IDEA 看源码必备技能

    最近正好也没什么可忙的,就回过头来鼓捣过去的知识点,到Servlet部分时,以前学习的时候硬是把从上到下的继承关系和接口实现记得乱七八糟. 这次利用了IDEA的diagram,结果一目了然,也是好用到炸裂,就此分享. 1.查看图形形式的继承链 在你想查看的类的标签页内,点击右键,选择 Diagrams,其中有 show 和 show ... Popup,只是前者新建在标签页内,后者以浮窗的形式展示: 实际上,你也可以从左边的项目目录树中,对你想查看的类点击右键,同样选择Diagrams,效果是一

  • 超详细MySQL使用规范分享

    最近涉及数据库相关操作较多,公司现有规范也不是太全面,就根据网上各路大神的相关规范,整理了一些自用的规范用法,万望指正. 数据库环境 dev: 开发环境 开发可读写,可修改表结构.开发人员可以修改表结构,可以随意修改其中的数据但是需要保证不影响其他开发同事. test: 测试环境 开发可读写,开发人员可以通过工具修改表结构. online: 线上环境 开发人员不允许直接在线上环境进行数据库操作,如果需要操作必须找DBA进行操作并进行相应记录,禁止进行压力测试. 重点的问题,各个环境的mysql服

  • python UIAutomator2使用超详细教程

    一.环境要求 python 3.6+ android 4.4+ 二.介绍 uiautomator2 是一个可以使用Python对Android设备进行UI自动化的库.其底层基于Google uiautomator,Google提供的uiautomator库可以获取屏幕上任意一个APP的任意一个控件属性,并对其进行任意操作. 三.库地址 GitHub地址: https://github.com/openatx/uiautomator2 https://github.com/openatx/uiau

  • SpringBoot整合MyBatis超详细教程

    1.整合MyBatis操作 前面一篇提到了SpringBoot整合基础的数据源JDBC.Druid操作,实际项目中更常用的还是MyBatis框架,而SpringBoot整合MyBatis进行CRUD也非常方便. 下面从配置模式.注解模式.混合模式三个方面进行说明MyBatis与SpringBoot的整合. 1.1.配置模式 MyBatis配置模式是指使用mybatis配置文件的方式与SpringBoot进行整合,相对应的就有mybatis-config.xml(用于配置驼峰命名,也可以省略这个文

  • 超详细教你怎么升级Mysql的版本

    一.前言 将mysql5.7 升级为mysql 8.0 准备两个压缩包! 二.备份数据库 1.cmd进入原来数据库中的路径 2.输入命令  mysqldump -u root -p --all-databases > D:\JAVA_Installation\MySQL\data\Backup.sql 1.是你mysql的用户名  平时登录数据库用的用户名 2.保存备份文件的路径 3..sql文件 不要提前建立,它会自动新建. 会进行输入密码,完毕后 备份成功 三.卸载原来的Mysql 111.

  • Linux Samba服务器超详细安装配置(附问题解决)

    目录 Samba服务器介绍 Samba服务器组件 Samba服务器相关的配置文件 安装Samba 第一种方式:yum安装 第二种方式:安装包安装 配置Samba 修改配置文件 添加用户并设置密码 重启Samba服务器 登录Samba 问题汇总及补充 网络选择 防火墙问题 权限问题 无法访问 自动连接 在嵌入式系统开发应用平台中,tftp.nfs和samba服务器是最常用的文件传输工具,tftp和nfs是在嵌入式Linux开发环境中经常使用的传输工具,samba则是Linux和Windows之间的

  • JS 函数的 call、apply 及 bind 超详细方法

    目录 JS 函数的 call.apply 及 bind 方法 一.call() 方法 1.call()方法的模拟实现 二.apply() 方法 1.apply()方法的模拟实现 三.bind() 方法 1.bind() 方法的模拟实现 四.总结 JS 函数的 call.apply 及 bind 方法 一.call() 方法 调用 call() 方法会立即执行目标函数,同时改变函数内部 this 的指向.this 指向由方法的第一个参数决定,后面逐个列举的任意个参数将作为目标函数的参数一一对应传入

  • SpringBoot整合mybatis-plus快速入门超详细教程

    目录 前言 mybatis-plus 简介 mybatis-plus 优点 相关链接 mybatis-plus实例 1.示例项目结构 2.数据库准备 3.pom.xml: 4.application.yml 5.User.java 6.UserMapper.java 7.UserServiceImpl.java 8.测试类 mybatis-plus的crud: 1.insert操作: 2.select操作: 3.update操作: 4.delete操作: 总结 前言 mybatis-plus 简

随机推荐