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

malloc/free和new/delete的异同

一、基本概念

     malloc/free:

1、函数原型及说明:

      void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。

      void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。

 

2.内存操作:

     malloc函数的参数是接受需要分配的内存字节数,如果内存能够满足请求量,那么将会返回:指向被分配的内存块起始位置

     free函数释放的是指针指向的内存(不是释放的指针本身,不会删除指针本身),其中指针必须指向所释放内存空间的首地址

 

new/delete:

1.操作时发生事件:

     new的时候会有两个事件发生:1).内存被分配(通过operator new 函数)  2).为被分配的内存调用一个或多个构造函数构建对象

     delete的时候,也有两件事发生:1).为将被释放的内存调用一个或多个析构函数  2).释放内存(通过operator delete 函数)

2.特殊应用:

   使用delete是未加括号,delete便假设删除对象是单一对象。否则便假设删除对象是个数组

   因此,如果在调用new时使用了[],则在调用delete时也使用[],如果你在调用new的时候没有[],那么也不应该在调用时使用[]。

 

二、malloc/free 和new/delete 的本质区别:

1.malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符

2.new能够自动分配空间大小

3.对于用户自定义的对象而言,用maloc/free无法满足动态管理对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++需要一个能对对象完成动态内存分配和初始化工作的运算符new,以及一个能对对象完成清理与释放内存工作的运算符delete---
简而言之 new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细的工作,而malloc/free不能。

 

三、联系

既然new/delete的功能完全覆盖了malloc/free,为什么C++还保留malloc/free呢?因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete,malloc/free必须配对使用。

 

四、使用范例

 

void * malloc(size_t size);

用malloc 申请一块长度为length 的整数类型的内存,程序如下:

int *p = (int *) malloc(sizeof(int) * length); 

我们应当把注意力集中在两个要素上:“类型转换”和“sizeof”。

1. malloc 返回值的类型是void *,所以在调用malloc 时要显式地进行类型转换,将void * 转换成所需要的指针类型。

2.malloc 函数本身并不识别要申请的内存是什么类型,它只关心内存的总字节数。

 

 void free( void * memblock );

为什么free 函数不象malloc 函数那样复杂呢?这是因为指针p 的类型以及它所指的内存的容量事先都是知道的,语句free(p)能正确地释放内存。如果p 是NULL 指针,那么free

对p 无论操作多少次都不会出问题。如果p 不是NULL 指针,那么free 对p连续操作两次就会导致程序运行错误。

 

new/delete 的使用要点

运算符new 使用起来要比函数malloc 简单得多,例如:

 

int *p1 = (int *)malloc(sizeof(int) * length); 
int *p2 = new int[length];

 

这是因为new 内置了sizeof、类型转换和类型安全检查功能。对于非内部数据类型的对象而言,new 在创建动态对象的同时完成了初始化工作。如果对象有多个构造函数,那么new 的语句也可以有多种形式。

如果用new 创建对象数组,那么只能使用对象的无参数构造函数。例如

Obj *objects = new Obj[100]; // 创建100 个动态对象 不能写成 
Obj *objects = new Obj[100](1);// 创建100 个动态对象的同时赋初值1 


      在用delete 释放对象数组时,留意不要丢了符号‘[]’。例如

delete []objects; // 正确的用法 
delete objects; // 错误的用法 后者相当于delete objects[0],漏掉了另外99 个对象。

转载于:https://www.cnblogs.com/MrZHj/p/4409842.html

相关文章:

  • java 下载spring的方法
  • Delphi项目构成之窗体文件(Form Files).DFM
  • quartz定时任务框架调度机制解析
  • 图片文件,图片文件流和BASE64加密字符串之间的转换,以及图片的BASE64加密字符串再jsp上如何显示...
  • 字符串处理函数的自定义函数实现
  • 判断两个链表是否相交(不带环)
  • 多线程 异步调用委托
  • 微信开发(一) 服务器配置
  • .net通用权限框架B/S (三)--MODEL层(2)
  • 开源库
  • STM32中断优先级彻底讲解
  • 基于PCA和SVM的人脸识别
  • markdonw 一个模版
  • android超快模拟器Ggenymotion的安装和配置
  • NSUserDefaults设置bool值重启后bool只设置丢失问题
  • [译] 怎样写一个基础的编译器
  • [译]Python中的类属性与实例属性的区别
  • 30秒的PHP代码片段(1)数组 - Array
  • canvas 绘制双线技巧
  • happypack两次报错的问题
  • Markdown 语法简单说明
  • nodejs实现webservice问题总结
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 前嗅ForeSpider教程:创建模板
  • 微信公众号开发小记——5.python微信红包
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • nb
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • (12)Linux 常见的三种进程状态
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (多级缓存)多级缓存
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (转)四层和七层负载均衡的区别
  • .NET 的程序集加载上下文
  • .NET 读取 JSON格式的数据
  • .NET下的多线程编程—1-线程机制概述
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @Validated和@Valid校验参数区别
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [20150707]外部表与rowid.txt
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [20161214]如何确定dbid.txt
  • [android] 切换界面的通用处理
  • [Android实例] 保持屏幕长亮的两种方法 [转]
  • [Android学习笔记]ScrollView的使用
  • [BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务
  • [BZOJ] 2427: [HAOI2010]软件安装
  • [CLR via C#]11. 事件
  • [C语言]——C语言常见概念(1)
  • [C语言]——内存函数
  • [Java][算法 双指针]Day 02---LeetCode 热题 100---04~07