C++的new和delete

2023-10-31

一、new和delete

1、在C++中堆内存的分配和释放是通过new和delete 来操作的,他们和C语言的malloc和free有什么区别呢?

new的底层也是通过malloc来开辟内存的,new比malloc 多一项功能,就是开辟完内存,还可以进行初始化操作,

如:int* p=new int(10);

上面是new的基本操作,10代表堆上开辟的整型内存的初始值,如果是自定义类类型的话,如下:

Test *p=new Test();

这个语句不仅会在堆上开辟Test类型大小的一块内存,还会调用Test类的默认构造函数构造出一个对象出来,这些都是malloc办不到的

2、delete 比free 多一项功能就是在释放内存之前,还可以析构指针指向的对象,new和delete配对使用,尽量不要交叉使用,以免产生不可预期的问题。

3、new开辟内存失败是抛出 bad_alloc类型的异常,因此代码上要捕获该类型的异常才能正确的判断堆内存是否分配成功,malloc内存开辟失败返回的是NULL指针。

4、new和delete不仅仅是运算符,它们实际上是运算符重载函数的调用,对应的函数名是operator new和operator delete,可以在全局或者类的作用域中提供自定义的new和delete运算符的重载函数,以改变默认的malloc和free内存开辟释放行为,比如说实现内存池。

二、什么时候用new[]申请,可以用delete释放?

new和new[]的底层都是通过malloc开辟内存的,delete和delete[]底层都是通过free来释放内存的,那么C++里面为什么把单个元素的内存开辟释放和数组的内存开辟释放分开呢?对了,因为在C++里面,开辟内存和构造函数是一起发生的,析构函数和释放内存是一起发生的。

int *p=new int;   delete p;

int *p=new int ; delete[]p;

int *p=new int[10] ;delete []p;

int *p=new int[10]; delete p;

看上面的代码,对于内置类型来说,这样混用是可以的,因为对于内置类型没有什么所谓的构造和析构,因此在这里的内存管理和调用malloc,free的含义是一样的,不存在什么问题,但在编程过程中最好不要这样写。

对于下面的类类型:

class Test

{

    public:

    Test() {}

private:

    int ma;

};


Test *p=new Test;   delete p;

Test *p=new Test;delete[]p;

Test *p=new Test[10];   delete []p;

Test *p=new Test[10];  delete p;

以上4条代码,也不存在任何问题,因为这个类没有提供析构函数,也就是说Test类对象不需要进行任何有效的析构,那么delete就只剩完成free的功能就行了,那么什么时候需要配对使用呢?看看下面的代码:

class Test

{

 public:

    Test() {}

    ~Test() {}

private:

    int ma;

};

Test *p=new Test;   delete p;       //ok 

Test *p=new Test;    delete[]p;    //程序崩溃

Test *p=new Test[10]; delete[]p;   //ok

Test *p=new Test[10];  delete p;    //程序崩溃

这个Test类和上面的有什么不一样吗? 此时有自定义的析构函数了,那么我们来分析一下new和delete的具体操作是怎么进行的!

Test *p=new Test;    delete[] p;在内存上开辟了4字节的内存,如下:


但是当你去delete[]的时候,它是从哪里释放内存的?



为什么它会减4个字节开始释放呢? 因为定义了析构函数,在释放内存之前需要在内存中析构对象,你写个delete[]p,编译器就认为这里有很多对象需要析构,多少个对象呢?记录对象个数的数字就在对象内存上面的4个字节存放,因为它从那里开始释放内存了,这肯定是发生错误的。

那么 Test *p=new Test[10];  delete p  呢?如下图:


因此,当自定义类型时,而且提供了析构函数的时候,那么new和delete千万不要混用,会导致对象的析构和内存释放有问题,除此之外,new和delete 从逻辑上来说,是可以混用的,但是最好在编程时不要这么做,而且隐患很大。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++的new和delete 的相关文章

  • 是否可以使静态控件透明?

    我正在尝试实现一个静态控件 该控件刷新 更改文本 以响应每秒发生一次的某个事件 由于我不想每秒绘制整个客户区域 所以我决定使用静态控件 现在的问题是父窗口被蒙皮 这意味着它有自定义位图作为背景 而静态控件没有适应 所以我正在寻找使静态控件的
  • 如何使用 LINQ ForEach 更改 List

    我有一个List
  • 根据当前文化调用不同(本地化)视图

    我在用着LocalizationAttribute它实现了ActionFilterAttribute本地化视图 我简单地说 Localize 在控制器上 我使用 LocalizeStrings resx 文件根据当前线程上的语言进行应用 一
  • 我们可以在 C# 中定义枚举的隐式转换吗?

    是否可以在 C 中定义枚举的隐式转换 可以实现这一目标的东西吗 public enum MyEnum one 1 two 2 MyEnum number MyEnum one long i number 如果没有 为什么不呢 有一个解决方案
  • MVC。网络错误:初始化字符串的格式不符合从索引 0 开始的规范

    我的连接字符串是
  • 求 a 范围内的 pow(a^b)modN

    对于给定的b and N以及一系列a say 0 n 我需要找到ans 0 n 1 where ans i 没有a s为此pow a b modN i 我在这里搜索的是可能的重复pow a b modN对于一系列a 以减少计算时间 例子 i
  • 您使用什么工具和技术来查找死代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您使用哪些工具和技术来查找 NET 中的死代码 过去 我用 Obsolete 属性修饰方法 传递 tr
  • 使用索引避免迭代器失效,维护干净的接口

    我创建了一个MemoryManager
  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • C# Visual Studio 动态代码片段

    我正在开发一个 WinForms 项目 每天都会执行一些重复性的任务 所以我认为创建代码片段 https msdn microsoft com en us library ms165394 v vs 110 aspx会帮助我 但它仅适用于固
  • 将标准库添加到C++ eclipse项目中

    一个 非常 新手 C 问题 有没有办法自动将标准库添加到 C eclipse 项目中 我安装了 CDT 主要功能插件 您可以手动添加 STL 标头的路径路径和符号 gt 包含选项卡 http help eclipse org galileo
  • 在 Windows 服务中使用 OleDb 从 Excel 读取数据?

    免责声明 我知道这是一种不好的做事方式 这是我们与客户的唯一选择 Problem 我们需要每隔 x 时间从 Excel 文件读取数据 数据通过第三方 Excel 插件不断变化 应用程序的环境是 Windows XP SP1 和 Net 2
  • 用于 C/C++ 的独立跨平台 (Windows/Linux) 文件压缩?

    我正在寻找一个 最好是小的 C 或 C 开源库 我可以将其包含在我的 MIT 许可项目中 托管在 google 代码上 我是一名业余爱好 C C 程序员 所以我并不那么先进 但我只知道为名为 SA MP 的应用程序 适用于 Windows
  • 如何在 WCF 中反序列化自定义 SOAP 标头?

    我正在尝试向通过 WCF 的所有 SOAP 请求添加自定义标头 我发现这篇精彩的文章 http blogs msdn com b mohamedg archive 2012 10 21 adding custom soap headers
  • 如何让 PCRE 与 C++ 一起使用?

    这是一个新手问题 但我希望我能尽可能清楚地表达我的问题 我正在尝试用 C 进行模式匹配 我已经从以下位置下载了 PCRE 的 Win32 版本here http gnuwin32 sourceforge net packages pcre
  • 没有类型的 IEnumerable 属性

    我正在尝试创建一个类似于来自 MSDN 的官方 DataGrid ItemsSource 的属性 public IEnumerable ItemsSource get set 这提供了对任何派生类中任何类型的支持 有了这个 我可以设置类似的
  • Subsonic 3 ActiveRecord 嵌套选择导致 NotIn 错误?

    我有以下 Subsonic 3 0 查询 其中包含嵌套的 NotIn 查询 public List
  • 如何进行平衡组捕获?

    假设我有这个文本输入 tes tR R abc aD mnoR xyz 我想提取 ff 输出 R abc R xyz D mnoR xyz R R abc aD mnoR xyz 目前 我只能使用平衡组方法提取组内的内容 如中所示msdn
  • 矩阵行列式算法 C++

    我是编程新手 我一直在寻找一种找到矩阵行列式的方法 我在网上找到了这段代码 但我很难理解这里的算法 我对递归的基础没有问题 但继续和主循环我很难理解 非常感谢任何可以向我解释该算法的人 int determ int a MAX MAX in
  • 有关 Endian 性和 .Net 的详细信息?

    我有几个关于字节顺序的问题 这些问题足够相关 我保证将它们作为一个问题提出 1 字节顺序是由 Net还是由硬件决定的 2 如果是由硬件决定的 我怎样才能在C 中找出硬件的字节序 3 字节序是否影响二进制交互 例如 OR AND OR 或移位

随机推荐

  • Vue:子组件使用的细节,子组件中的data,ref的使用,

    我们创建一个table div table tbody tbody table div
  • 【工号不够用了怎么办?】

    题目描述 工号不够用了怎么办 3020年 空间通信集团的员工人数突破20亿人 即将遇到现有工号不够用的窘境 现在 请你负责调研新工号系统 继承历史传统 新的工号系统由小写英文字母 a z 和数字 0 9 两部分构成 新工号由一段英文字母开头
  • 会话状态保持,JSESSIONID,COOKIE,URL重写

    居然有3W的访问量 好 我就把session和cookie的关系先来个总结 注意 是最最简单直白明了的总结了 http协议 协议 协议 重要的说3遍 http协议主要有2大块 请求头和请求体 cookie在http请求头里 就是一个由多个K
  • webpack的基本的配置和应用

    借用下官网的图 从图中我们了解webpack功能就是把带有依赖的模块打包成单一相同类别的静态资源文件 接下来帮大家分析下webpack的核心概念及一些辅助配置 一 核心概念 webpack核心概念有这些 入口 entry 输出 output
  • VMware vCenter Server 证书过期解决

    问题现象 今天一上班同事反应虚拟平台登录不了了 验证功能正常 输入正确密码后跳转如下错误界面 查看证书可以看见证书今天要过期了 但是当时还没到11 53 13 却已经用不了了 原因 从vCenter 6 5 Update2 GA Date
  • 数据结构图在python中的应用

    程序世界里 有很多的数据结构 比如 堆 栈 链表等等 今天要讲的就是图数据结构啦 相信大家都使用过或者听说过图数据库吧 我们就来看看最简单的图数据结构算法 首先先来看一下图长什么样 从上图能看出 比如节点A可以到达C D B 节点B只能到达
  • 阶乘和数(python3)

    问题描述 一个正整数如果等于组成它的各位数字的阶乘之和 则该正整数称为阶乘和数 例如正整数145 1 4 5 等于145 因此145就是一个阶乘和数 输入一个正整数 计算它的各位数字的阶乘之和 并判断它是否是一个阶乘和数 注意 输入的正整数
  • [Git系列] Git 基本概念

    版本控制系统 版本控制系统是一种帮助软件开发者实现团队合作和历史版本维护的软件 一个版本控制系统应具备以下列出的这几个基本功能 允许开发者并发工作 不允许一个开发者覆写另一个开发者的修改 保存所有版本历史 版本控制系统可以分为如下两类 集中
  • Python解析JSON数据的方法

    Python解析JSON数据的方法 在Python中 我们可以使用内置的json模块来解析JSON数据 下面是一个简单的例子 import json JSON数据 json str name Alice age 25 is student
  • Linux命令:top

    top命令 用于动态地监视进程活动与系统负载等信息 top 23 27 36 up 30 min 0 users load average 0 52 0 58 0 59 Tasks 6 total 1 running 5 sleeping
  • 如何使用anaconda创建环境

    使用anaconda创建环境 方法一 直接从ANACONDA NAVIGATOR里面创建 不建议 但是这种不太好 这种创建的环境 最后很难在命令指示符上成功安装库 所以不建议 本人踩了很多次雷才发现的 方法二 从Anaconda Promp
  • weston 简介

    参考 weston wiki Weston Gentoo Wiki weston 1 Linux man pages code tools Weston 1 12 0 非常详尽 多图慎入 Wayland与Weston简介 云 社区 腾讯云
  • 根据pid查端口_PID控制的原理及常用口诀总结

    PID控制器 比例 积分 微分控制器 是一个在工业控制应用中常见的反馈回路部件 由比例单元比例P proportion 积分单元I integration 和微分单元D differentiation 组成 PID控制器作为最早实用化的控制
  • [小技巧] git 取得两个 tag 之间的 commit

    参考 http stackoverflow com questions 5863426 get commit list between tags in git git log pretty oneline tagA tagB If you
  • JS逆向——百度翻译

    我们在爬虫时经常会遇到一些奇怪的参数 比如百度翻译的sign 网易云音乐的params等 这个时候就要用js逆向的技术来获取参数的构造方法 前置准备 Chorme浏览器 Sublime编译器 Python 爬取链接 https fanyi
  • matlab 代码转 Python

    可以使用 MATLAB 工具箱 MATLAB 集成工具 将 MATLAB 代码转换为 Python 代码 这个工具箱可以自动将大部分 MATLAB 代码转换为类似的 Python 代码 并且可以自动处理一些类型和语法上的差异 在 MATLA
  • nrf52832通过i2c官方库nrf_drv_twi读取tmp117温度

    twi调试过程如下 1 代码实现 分别实现对nrf drv twi init nrf drv twi rx nrf drv twi tx相关官方库的调用 2 修改工程配置文件sdk config h 增加TWI的相关配置 参考 nRF5 S
  • WSL2安装google chrome浏览器

    一 环境 Windows 11 Ubuntu 22 04 二 安装google chrome步骤 官方文档 1 创建文件夹 mkdir chrome 2 进入目录 cd chrome 3 下载chrome压缩包 sudo wget http
  • 计量经济学及Stata应用 5.12 多元回归的Stata实例

    1 多元回归 regress y x1 x2 x3 reg y x1 x2 x3 2 解释定义 1 右上角 Number of obs 样本容量N F n N F统计量 自由度为k 约束条件 m N K 检验整个方程的联合显著性 Prob
  • C++的new和delete

    一 new和delete 1 在C 中堆内存的分配和释放是通过new和delete 来操作的 他们和C语言的malloc和free有什么区别呢 new的底层也是通过malloc来开辟内存的 new比malloc 多一项功能 就是开辟完内存