1、先介绍malloc/free的用法:

原型函数: void *malloc(long NumBytes);

该函数分配了NumBytes个字节的内容,分配的空间是堆空间

malloc()根据用户所需分配内存的大小n (bytes)在“堆链表”(见未使用过得堆内存)里搜索。直到搜索到一个大于等于n字节的堆内存块为止。如果此堆内存块的大小刚好为n,则直接将首地址返回给用户;如果此内存块的大小大于n,则将此块堆内存分裂,将大于n部分的堆内存留在可用堆内存中,以“堆链表”的形式和其它未分配的堆内存发生联系。

如果整个堆链表所代表的堆内存块都没有大于等于n的堆内存块,系统将给“堆链表”链接一个更大的区域供其使用。要是这一步也失败了,malloc()函数就返回NULL给用户。

malloc()函数分配内存成功则返回可用堆内存块的首地址,若分配失败则返回空。在使用malloc()后一定要判断堆内存是否成功。若对内存分配未成功使用指针操作内存也会使程序出现异常。动态分配内存时要采取以下结构:

char *pL =NULL;
……
pL = (char *)malloc( sizeof(char) * size);
if(pL)
{

}

分配成功后,得到的堆内存首地址一定要保存,不然后来无法释放堆内存而造成内存泄露。而且不可使用未初始化的pL指向的内存块。

malloc函数只是完成内存的分配,但是并没有对分配的内存进行初始化设定,一般在进行malloc函数后面接着的语句就是内存空间初始化语句。

char * ps = (char*) malloc(sizeof(char)*15);
strcpy(ps, "hello world");

free函数与malloc()函数配对使用,释放malloc函数申请的动态内存。对于free(p)这句语句,如果p 是NULL 指针,那么free 对p 无论操作多少次都不会出问题。如果p 不是NULL 指针,那么free 对p连续操作两次就会导致程序运行错误。

为了防止以上错误,在使用free函数之前,应该先判断指针是否为NULL;

if(pL)
{
free(pL);
pL = NULL;
}

  

2、new和delete的用法

new和delete运算符是用于动态分配和撤销内存的运算符,解决了变量和对象在编译之前就要确定大小的问题,如数组必须大开小用,指针必须指向一个已经存在的变量或对象。

  一、new用法

  1.开辟单变量地址空间

使用new运算符时必须已知数据类型,new运算符会向系统堆区申请足够的存储空间,如果申请成功,就返回该内存块的首地址,如果申请不成功,则返回零值。

new运算符返回的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过该指针来间接操作的,而动态创建的对象本身没有标识符名。

一般使用格式:
        格式1:指针变量名=new 类型标识符;
        格式2:指针变量名=new 类型标识符(初始值);
        格式3:指针变量名=new 类型标识符 [内存单元个数];

说明:格式1和格式2都是申请分配某一数据类型所占字节数的内存空间;但是格式2在内存分配成功后,同时将一初值存放到该内存单元中;而格式3可同时分配若干个内存单元,相当于形成一个动态数组。例如:

1)new int;  //开辟一个存放整数的存储空间,返回一个指向该存储空间的地址。int *a = new int 即为将一个int类型的地址赋值给整型指针a

2)int *a = new int(5) 作用同上,但是同时将整数空间赋值为5

  2.开辟数组空间

对于数组进行动态分配的格式为:

指针变量名=new 类型名[下标表达式];
       delete [ ] 指向该数组的指针变量名;

两式中的方括号是非常重要的,两者必须配对使用,如果delete语句中少了方括号,因编译器认为该指针是指向数组第一个元素的指针,会产生回收不彻底的问题(只回收了第一个元素所占空间),加了方括号后就转化为指向数组的指针,回收整个数组。

delete []的方括号中不需要填数组元素数,系统自知。即使写了,编译器也忽略。

请注意“下标表达式”不必是常量表达式,即它的值不必在编译时确定,可以在运行时确定。

一维: int *a = new int[100];    //开辟一个大小为100的整型数组空间

二维: int **a = new int[5][6]

三维及其以上:依此类推.

一般用法: new 类型 (初值)

  二、delete用法

  1. 删除单变量地址空间

int *a = new int;

delete a;   //释放单个int的空间

  2. 删除数组空间

int *a = new int[5];

delete []a;    //释放int数组空间

区别:

0.       属性

new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持。

1.       参数

使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。

2.       返回类型

new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

3.       分配失败

new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。

4.      自定义类型

new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。

malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。

5.      重载

C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载。

6.       内存区域

new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。

C中的malloc/free与C++中的new/delete的用法与区别的更多相关文章

  1. javascript中window与document对象、setInterval与setTimeout定时器的用法与区别

    一.写在前面 本人前端菜鸟一枚,学习前端不久,学习过程中有很多概念.定义在使用时容易混淆,在此给向我一样刚踏入前端之门的童鞋们归纳一下.今天给大家分享一下js中window与document对象.se ...

  2. WordPress翻译中 __()、_e()、_x、_ex 和 _n 的用法及区别

    编译函数 WordPress使用了下面几个函数来方便语言本地化. __() _e() _x() _ex() _n() 以上所列的函数是用来包含所需翻译的字符串的,根据字符串的不同参数和输出类型,需要使 ...

  3. SQL查询中in、exists、not in、not exists的用法与区别

    1.in和exists in是把外表和内表作hash(字典集合)连接,而exists是对外表作循环,每次循环再对内表进行查询.一直以来认为exists比in效率高的说法是不准确的,如果查询的两个表大小 ...

  4. jquery easyui 中tab页添加其他页面,href与content的用法与区别

    //tab页增加 function addPanel(name,url){ var dd = $('#tt').tabs('exists',name); if(dd){ $('#tt').tabs(' ...

  5. PHP中PHP $_POST和PHP $_REQUEST及PHP $_GET的用法及区别

     笔者最近开始学习PHP语言大法,记录一下学习过程中遇到的知识点.          今天介绍的是php中有关 php $_post 和 php $_request 及 php $_get 的用法及区 ...

  6. 几个系统调用分析 glibc中的malloc调用和共享内存原理

    本文主要分析内存以及I/O相关的系统调用和库函数的实现原理,根据原理给出在使用过程中需要注意的问题和优化的侧重点,本文涉及到的系统调用包括readahead,pread/pwrite,read/wri ...

  7. 浅谈C中的malloc和free

    转自http://bbs.bccn.net/thread-82212-1-1.html非常感谢作者 浅谈C中的malloc和free 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的 ...

  8. (转)浅谈C中的malloc和free

    原帖及讨论:http://bbs.bccn.net/thread-82212-1-1.html 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的malloc()和free()两个函数 ...

  9. C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

      BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 : ...

随机推荐

  1. CentOS 7 (Linux) 下载百度网盘大文件

    这个方法不仅适合下载 "百度网盘" 中的文件,还可以下载磁链之类的,总之,就是能够加快下载速度的方法. (参考了网上的多篇文章,自行实践,成功下载度盘大文件,并且提升了下载速度) ...

  2. python: 反射机制;

    import comma def run(): inp = input('请输入要调用的函数').strip(); if hasattr(comma,inp): fun = getattr(comma ...

  3. Hibernate的入门(概念1):

    什么是持久化类? 持久化类的编写规则? 区分自然主键和代理主键? 主键生成策略?

  4. ansible playbook 变量

    变量优先级 在命令中定义的变量(-e参数指定的) 在inventory中定义的变量(ansible_ssh_user等) 其他变量(role中.play中) 系统通过father_facts定义的变量 ...

  5. Visual Studio连接到TFS

    我在学校自己使用git,公司使用VSS,然后这个项目又使用TFS.Visual Studio连接到TFS是这样滴 1.点连接到团队项目 2.添加TFS服务器的url,写到你的http:XXX/tfs就 ...

  6. Memcached入门学习

    Memcached入门学习 学习网址:http://www.runoob.com/Memcached/Memcached-tutorial.html

  7. CentOS7 下 Hadoop 单节点(伪分布式)部署

    Hadoop 下载 (2.9.2) https://hadoop.apache.org/releases.html 准备工作 关闭防火墙 (也可放行) # 停止防火墙 systemctl stop f ...

  8. MyBatis-resultType 几种返回类型

    一.返回集合 1.返回JavaBean集合 public List<MyUser> selectMyUserByNameLike(String name); <!-- resultT ...

  9. excel vlookup简易样例【原】

    vlookup功能 vlookup主要用来做映射,就像java的map一样. 比如我要找id为2的学生对应的名字,那么在F7单元格录入=VLOOKUP(E7,$A$2:$B$4,2,FALSE) 实际 ...

  10. jQuery使用(三):DOM操作之val()方法操作表单元素value值

    操作表单元素属性value的值 <form action="./" method='GET'> <h3 >选择你喜欢的明星</h3> <s ...