当前位置: 首页 > news >正文

【C++】——new和delete与malloc和free的区别

【C++】——new和delete与malloc和free的区别

C语言提供了malloc和free用于开辟和释放内存,C++提供new和delete进行内存操作,本文将new和delete与malloc free做对比,便于理解和巩固知识。还讲解了为什么delete和delete[]不能混用

new

讲解new和malloc的区别,以及new的底层。

与malloc区别

  • malloc是函数,new是操作符,也是关键字。

  • malloc返回void*类型指针,new直接返回对象。

  • malloc只负责开辟空间,不负责对对象初始化,new除了开辟空间、还负责调用对象的构造函数完成初始化。

  • malloc需要传参开辟字节数,new传参对象类型和对象个数,由底层完成开辟空间的字节数的计算。

  • malloc开辟空间失败会返回NULLnew开辟空间失败会抛异常(抛异常符合现代编程风格,也方便和 try catch组合使用)。

底层实现

简介new的底层原理,为什么new不仅可以完成开辟空间、还可以完成初始化。(关于为什么delete[]和delete不能混用的部分在delete讲解

new的底层是operator newplacement newoperator new封装了malloc来开辟空间,placement new用完成构造函数的调用。以下代码使用底层方法完成new的功能:

// 对单个自定义类型对象new
// MyClass* obj = new MyClass(args); // 使用 new 创建空间
// 本质上
MyClass* obj = (MyClass*)operator new(sizeof(MyClass)); //使用operator new申请空间
new(obj)MyClass(args); // 使用placement new调用MyClass的构造函数,对空间初始化.后面的()用于构造函数传参,不传参默认调用默认构造函数// 对数组new
// MyClass* obj = new MyClass[size]{args); // 使用 new 创建空间
MyClass* arrayMemory = (MyClass*)operator new[](sizeof(MyClass) * size);
// 使用placement new[]构造数组
new(arrayMemory) MyClass[size]{MyClass(1, "对象1"),MyClass(2, "对象2"),MyClass(3, "对象3")
};
  • operator new:通过代码可以发现,operator newmalloc使用方法一样,不同的是,new封装了operator new,所以你可以通过重载operator new实现特定的类/全局,在自己规定的内存分配器中开辟空间。而operator new本质上就是malloc的封装

  • placement new:完成构造函数的调用。

delete

讲解delete和free的区别,一起为什么delete和delete[]不能混用。

和free的区别

  • free是函数,delete是操作符,也是关键字。
  • free只负责释放空间,不负责对对象调用析构函数,delete除了负责释放空间,还负责对对象调用析构函数。
  • free需要传参释放空间首部的指针起始位置,delete传参对象类型和对象个数,由底层完成调用析构函数的次数的计算。

底层实现

delete封装了operator deletedesturction(对应对象的析构函数)operator delete则是封装了free_dbge_来释放空间。

在使用delete时,本质是先调用析构函数,再释放空间。

为什么delete[]new[]搭配使用,deletenew搭配使用?

为了在使用delete时,编译器知道应该调用多少次析构函数,new开辟空间时,会在返回的指针前另外开辟size_t空间存储对象数目。

另外,如果不需要记录,编译器自然也不会开辟空间记录。比如内置类型、没有析构函数的情况下。

请添加图片描述

图解

通过查看内存验证

对于有析构函数的类的验证:
请添加图片描述

请添加图片描述

对于没有析构函数或者内置类型的验证:

请添加图片描述

关于new的小tips

另外,我们试一下如果删除了析构函数再去new一个数组出来会出现什么情况。

class A
{
public:A(){ c = 1;}~A() = delete; // 🚨 问题在这里!int c;
};
int main()
{A* p = new A[10];// 如果第5个对象构造时抛出异常,前4个需要析构// 如果整个new表达式失败,所有已构造对象需要析构return 0;
}

编译出错,这是为什么呢?

当你使用 new A[10] 时,编译器需要:

  • 构造10个A对象
  • 如果分配失败或数组生命周期结束,需要析构已构造的对象

由于 ~A() = delete,编译器无法生成析构数组元素的代码。

http://www.dtcms.com/a/431464.html

相关文章:

  • MD5的应用与实现
  • php做网站很快嘛竞价代运营厂家
  • 运维自动化之 Ansible 核心知识点总结
  • 高频基础面试题解析:字符串操作、数字运算、条件循环
  • 建设行业信息管理系统网站德阳网站制作
  • 笔记本安装Ubuntu 20.04其触摸板如何开启或关闭
  • 站长之家域名查询排行阿里云网站备案注销
  • 企业微网站建设网站开发版权归谁
  • 爬虫数据采集(实例分析1)
  • 大理旅游网站建设有口碑的做网站
  • 卓老师建站特色功能三门峡做网站
  • 网站建站维护运营湖北省建设工程网站
  • smss!SmpStartCsr函数分析之SmpLoadSubSystemsForMuSession3389远程桌面新进程csrss.exe的由来
  • 网络安全细则[特殊字符]
  • 网页设计中文本居中用什么代码项链seo关键词
  • 决策树算法基础:信息熵相关知识
  • C#基础08-面向对象
  • 网站建设公司费用网站开发遵循
  • php做网站 价格商城网站开发技术可行性分析
  • 10.仅使用 CSS 实现波浪形卡片 UI 设计
  • 太原市手机微网站建设网络推广都有哪些方式
  • display ospf interface 概念及题目
  • 专栏导航:《数据中心网络与异构计算:从瓶颈突破到架构革命》
  • 基层单位不能建设网站织梦做有网站有后台 能下载备份所有代码文件么
  • 爱网站关键词查询工具长尾美食网站建设项目预算
  • Swift 属性
  • 服务器做网站用什么环境好页游平台网站
  • 在手机上做网站是什么软件网店推广软件
  • 无锡网站建设服务公司如何给网站的关键词做排名
  • java线上问题排查-占用内存的大对象