new/delete与malloc/free的区别

参考:

https://blog.csdn.net/u013485792/article/details/51329541

https://www.cnblogs.com/lyl-312/p/5528892.html

http://www.cnblogs.com/QG-whz/p/5140930.html

https://blog.csdn.net/gukesdo/article/details/7506155

  本文在写作中参考了上述文章,特此感谢!

【导语】

之前对new和delete,malloc和free这两对组合只有个简单的了解,知道必须配合使用来对内存进行控制。近期在工作中用到了malloc和free,结果出现各种内存问题,解决了好久,记录一下当做回顾。

1   C++内存简介

1.1     内存分区

  在C++中内存分为5个区,分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

  堆:堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。

  栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

  自由存储区:自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。(new操作符从自由存储区上为对象动态分配内存空间)

  全局/静态存储区:这块内存是在程序编译的时候就已经分配好的,在程序整个运行期间都存在。例如全局变量,静态变量。

  常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量(const),不允许修改。

1.2     自由存储区

  那么自由存储区是否能够是堆(问题等价于new是否能在堆上动态分配内存),这取决于operator new 的实现细节。自由存储区不仅可以是堆,还可以是静态存储区,这都看operator new在哪里为对象分配内存。

特别的,new甚至可以不为对象分配内存!定位new的功能可以办到这一点:


new (place_address) type

place_address为一个指针,代表一块内存的地址。当使用上面这种仅以一个地址调用new操作符时,new操作符调用特殊的operator new,也就是下面这个版本:


void * operator new (size_t,void *) //不允许重定义这个版本的operator new

这个operator new不分配任何的内存,它只是简单地返回指针实参,然后右new表达式负责在place_address指定的地址进行对象的初始化工作。

所以有的文章简单的将new delete,malloc  free 理解为都是从堆中获取内存。下文中也是以此进行描述,知道基本原理即可。

  另外基于此,有的文章将C++内存的五个区划分为:堆、栈、全局/静态存储区、常量存储区和程序代码区。

  程序代码区:存放程序的二进制代码。

2   new,delete和malloc free的区别

  Ps:关于new和malloc之间的区别请参考下面这篇博客,里面讲解的很详细。

  http://www.cnblogs.com/QG-whz/p/5140930.html

  本文下面从自己的角度简单描述一下。

2.1     构造函数/析构函数

使用new操作符来分配对象内存时会经历三个步骤:

  第一步:调用operator new 函数(对于数组是operator new[])分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象。

  第二步:编译器运行相应的构造函数以构造对象,并为其传入初值。

  第三部:对象构造完成后,返回一个指向该对象的指针。

使用delete操作符来释放对象内存时会经历两个步骤:

  第一步:调用对象的析构函数。

  第二步:编译器调用operator delete(或operator delete[])函数释放内存空间。

总之来说,new/delete会调用对象的构造函数/析构函数以完成对象的构造/析构。而malloc则不会,malloc只是简单的分配一块内存给用户使用。

2.2     delete和free的区别

  首先free对应的是malloc;delete对应的是new;free用来释放malloc出来动态内存,delete用来释放new出来的动态内存空间。

  new/delete是C++的操作符,而malloc/free是C中的函数。

应用的区别为:

  1. 数组的时候int *p=(int*)malloc(10*sizeof(int)) 释放的时候 free(p)即可;这是因为编译器对malloc做了一些特殊的处理,以保证可以正确释放内存。

   而当int *p=new int[10]释放的时候应为delete []p,注意[]的作用说明释放的是一个数组的内存,如果delete p则只是释放的p[0],其余9个int的内存没有释放;这是因为当指明为[]的时候,编译器实际上是做了一个循环来释放这个数组的所有内存。

  2. 在类和对象的时候会有很大区别。在使用malloc和free来处理动态内存的时候,仅仅是释放了这个对象所占的内存,而不会调用这个对象的析构函数;使用new和delete就可以既释放对象的内存的同时,调用这个对象的析构函数。

共同之处:

  它们都是只把指针所指向的内存释放掉了,并没有把指针本身干掉。在free和delete之后,都需要把指向清理内存的指针置为空,即p=NULL,否则指针指向的内存空间虽然释放了,但是指针p的值还是记录的那块地址,该地址对应的内存是垃圾,p就成了“野指针”。

  即free和delete之后,是把从堆中获取的内存释放,这部分内存现在可以分配给其它使用。但是栈中的指针本身依然存在,并仍然指向该部分内存。如果不把指针设置为NULL。后面仍然去调用该指针,可以获得这部分内存中的值。但是这部分内存中的值是不确定的,有可能已经被其它程序调用,即“野指针”。如果只是单纯的把指针设置为NULL,没有调用free和delete会导致内存泄露。即从指针判断的话,已经无法访问内存。但是由于没有调用free和delete,导致系统以为这部分内存依然在使用,程序执行过程中无法分配给其它部分,导致内存浪费。

  如果程序较长,我们通常在使用一个指针前会检查p!=NULL,这样就起不到作用了。此时如果再释放p指向的空间,编译器就会报错,因为释放一个已经被释放过的空间是不合法的。而将其置为NULL之后再重复释放就不会产生问题,因为delete一个0指针是安全的。

在这里关于指针和动态申请的内存空间总结如下:

  1. 指针消亡了,并不表示它指示的动态内存会自动释放;

  2. 动态内存释放掉了,如果这个内存是一个动态对象,则并不表示一定会调用这个对象的析构函数;

      动态内存释放掉了,并且调用了析构函数,并不表示指针会消亡或者自动变成了NULL。

原文地址:https://www.cnblogs.com/szBeginner/p/9241237.html

时间: 2024-10-10 01:17:17

new/delete与malloc/free的区别的相关文章

new/delete 与 malloc/free的区别

一.概述 在C++中,申请动态内存与释放动态内存用new/delete 与 malloc/free都可以,而且他们的存储方式相同,new/malloc申请的动态内存位于堆中,无法被操作系统自动回收,需要对应的delete也free释放空间. malloc/free是C/C++语言的标准库函数,在C语言中需要头文件#include<stdlib.h>的支持.而new/delete是C++的运算符.对于类对象而言,malloc/free无法满足动态对象的要求,对象要求在创建的同时自动执行构造函数,

new/delete 和malloc/free 的区别一般汇总

一.基本概念 malloc/free: 1.函数原型及说明: void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败,则返回一个空指针(NULL). void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由. 2.内存操作: malloc函数的参数是接受需要分配的内存字节数,如果内存能够满足请求量,那么将会返回:指向被分

new/delete 和 malloc/free 的区别

1.malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存.但是new能够自动分配空间大小,而malloc需要计算字节数. 2.对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求.对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数.由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free. 因此C++语言

new delete和malloc free的区别

部分内容摘自:http://www.52rd.com/bbs/Archive_Thread.asp?SID=209143&TID=3&WebShieldDRSessionVerify=QWlrR3KW8IElo27YO6zv 一.他们分别是什么 new和delete是c++中的操作符,malloc和free是c/c++的标准库函数. 在使用完分配的内存时,要及时用delete和free进行内存释放,避免内存泄漏. 二.他们之间的区别 1.malloc的原型为:void * malloc(s

new/delete、malloc/free 的区别

相同点 1.都可以动态的申请或释放内存 2.存储方式相同,动态申请的内存都存放在堆中,无法自动释放,要调用对应的delete和free 区别 1.new能自行的计算需要分配的空间,malloc需要手动计算字节数 int *p1 = new int[10]; int *p2 = (int*)malloc(10*sizeof(int)); 2.new和delete直接带具体类型的指针,malloc和free返回void类型的指针 void *p2 = malloc(10*sizeof(int));

C++中,new/delete和malloc/free的区别

1.new/delete是C++的操作符,而malloc/free是C中的函数. 2.new做两件事,一是分配内存,二是调用类的构造函数:同样,delete会调用类的析构函数和释放内存.而malloc和free只是分配和释放内存. 3.new建立的是一个对象,而malloc分配的是一块内存:new建立的对象可以用成员函数访问,不要直接访问它的地址空间:malloc分配的是一块内存区域,用指针访问,可以在里面移动指针:new出来的指针是带有类型信息的,而malloc返回的是void指针. 4.ne

new 、delete和malloc、free的解析及区别

在c语言中使用函数malloc和free来进行内存管理(分配与释放),在c++中则提供了运算符new和delete来做同样的工作,后者比前者性能更优越,使用更方便更灵活. 1.new用于内存分配的基本形式为: 指针变量名=new 类型 在程序运行过程中new是从堆的一块自由存储区中为程序分配一块与类型字节数相适应的内存空间,并将该块内存的首地址存于指针变量中. eg. int *p;   //声明一个整形指针变量p p=new int;   //动态分配一个存放int型数据的内存空间,并将首地址

new/delete 和 malloc/free有什么区别和联系

区别: 1. new/delete是C++的操作符,malloc/free是C/C++标准库函数. 2. new分为两步的:第一步是申请内存,第二步则是调用构造函数初始化对象.同样,在调用delete的时候,需要先调用析构函数,然后再回收堆内存.malloc只会根据参数分配内存,默认返回指向void*的指针,同样free释放malloc分配的内存. 3.malloc/free是new/delete的一个子集. 共同点: 1. 都必须配对使用,这里的配对使用,可不能理解为一个new/malloc就

关于new,delete,malloc,free的一些总结

首先,new,delete都是c++的关键字并不是函数,通过特定的语法组成表达式,new可以在编译的时候确定其返回值.可以直接使用string *p=new string("asdfgh");来直接赋值.这其中在调用new分配空间得时候的时候,系统其实直接调用了类或结构的构造函数来对对其进行赋值,这个过程就相当于是string p=string("asdfgh"); 或者string p("asdfgh");(其实上面的过程还是有一定的不同之处: