new / delete和malloc / free有什么区别?


Answers:


465

新/删除

  • 分配/释放内存
    1. 从“免费存储”分配的内存
    2. 返回一个全类型的指针。
    3. 新版(标准版)从不返回NULL(将抛出故障)
    4. 用Type-ID调用(编译器计算大小)
    5. 具有显式处理数组的版本。
    6. 重新分配(以获取更多空间)不是直观地处理的(由于复制构造函数)。
    7. 他们是否调用malloc / free由实现定义。
    8. 可以添加一个新的内存分配器来处理内存不足的问题(set_new_handler)
    9. 运算符new / delete可以合法覆盖
    10. 用于初始化/销毁对象的构造函数/析构函数

malloc /免费

  • 分配/释放内存
    1. 从“堆”分配的内存
    2. 返回一个空*
    3. 失败时返回NULL
    4. 必须以字节为单位指定所需的大小。
    5. 分配数组需要手动计算空间。
    6. 简单地重新分配更大的内存块(无需担心复制构造函数)
    7. 他们不会打电话给新的/删除的
    8. 无法将用户代码拼接到分配序列中以帮助减少内存。
    9. 不能合法地覆盖malloc / free

表功能比较:

 Feature                  | new/delete                     | malloc/free                   
--------------------------+--------------------------------+-------------------------------
 Memory allocated from    | 'Free Store'                   | 'Heap'                        
 Returns                  | Fully typed pointer            | void*                         
 On failure               | Throws (never returns NULL)    | Returns NULL                  
 Required size            | Calculated by compiler         | Must be specified in bytes    
 Handling arrays          | Has an explicit version        | Requires manual calculations  
 Reallocating             | Not handled intuitively        | Simple (no copy constructor)  
 Call of reverse          | Implementation defined         | No                            
 Low memory cases         | Can add a new memory allocator | Not handled by user code      
 Overridable              | Yes                            | No                            
 Use of (con-)/destructor | Yes                            | No                            

从技术上讲,new分配的内存来自“免费存储”,而malloc分配的内存来自“堆”。这两个区域是否相同是实现细节,这是不能将malloc和new混合的另一个原因。


12
有人可以编辑以详细说明“免费存储”而不是堆吗?进程的堆是众所周知的与语言无关的(?)操作系统级概念;“免费商店”来自哪里?
einpoklum '16

1
@einpoklum:它们只是存储区的名称。两者都与称为“堆”的语言概念或“进程堆”的os概念无关。故意将C ++定义为与Platform / OS / Compiler无关。因此,使用诸如“进程堆”之类的特定OS概念将破坏标准的灵活性。
马丁·约克

4
@winterlight:以前是真的,但现在不再是。参见:linux.die.net/man/3/free If ptr is NULL, no operation is performed.
Martin York

2
@LokiAstari它看起来确实像'heap','free store'和'dynamic memory / storage'的同义词:在Bjarne Stroustrup的A Tour of C ++中,他说:“ new操作员从免费存储区中分配内存(也称为动态内存)。)的C ++ 14标准,对第3.7.4 动态存储表示“对象可以动态地执行程序(1.9)期间创建,使用新的表达式(5.3.4),并使用删除表达式破坏。”
最大Heiber

2
@mheiber:这意味着它们可以相同。并且有几种实现通过调用malloc来实现new(请注意,明确禁止使用另一种方法)。但是几种实现方式使这些存储区域完全分开。仍然将它们分开的原因是,这允许以与C内存管理不同的方式优化C ++内存管理代码。关键是:它们可以相同,但您不能假设它们是相同的。
马丁·约克

81

最相关的区别是,new运算符先分配内存,然后调用构造函数,再delete调用析构函数,然后重新分配内存。


22
严格来说,new运算符只是分配内存。是新表达式,它调用new运算符,然后在分配的内存中运行构造函数。
唐·韦克菲尔德

另一个区别是分配内存的位置。最近,我在某个地方看到malloc / free在堆上运行,而new / delete在另一个我现在不知道的内存区域中运行。(不过,可以说其他区域可能被视为另一个堆。)
RobH

2
@mgb:是的,您正确的是,对象是在“应用程序堆”或堆栈上分配的。但是 @RobH指的是标准所谓的“应用程序堆”的不同部分。其中有“堆”,malloc从中分配内存,有“免费存储”,new从中分配内存。尽管在某些实现中,这些区域确实重叠(这是实现细节)。
马丁·约克

1
您的陈述是100%正确的,但只是不回答所提出的问题,请参阅下面的答案,这是其票数多于您的原因。
Murali 2010年

1
我只是想说的是,至少应该提及malloc / free才能使它符合您的回答所缺乏的比较条件。但是,这是一个相关且准确的声明,因此,赞扬我希望你理解我的观点。无论如何,如果只有我允许我收回我的反对票,我将全心全意。
Murali 2010年

30

new调用对象的ctor,delete调用dtor。

mallocfree只是分配和释放原始内存。


原始内存是什么意思?
破坏者

3
原始内存没有做任何事情。尚未构造任何对象,也没有任何内容被复制到其中,并且在大多数情况下,以前的内容未被覆盖。
詹姆斯·柯伦

14

new/ delete是C ++,malloc/ free来自旧的C语言。

在C ++中,new调用对象构造函数并delete调用析构函数。

mallocfree来自OO之前的黑暗时代,仅分配和释放内存,而不执行对象的任何代码。


9
“来自OO之前的黑暗时代”听起来像是在暗示new / delete 比malloc / free 更好,而实际上,更好或更糟,它们具有不同的用途。请注意,我并不是让您失望的人,我只是在猜测。
Graeme Perrow,

13

在C ++ new/ delete相应地调用构造/析构。

malloc/ free只是从堆中分配内存。new/ delete以及分配内存。


10

唯一的相似之处是malloc/ new都返回一个指向堆中某些内存的指针,并且都保证一旦返回了这样的内存块,除非您先释放/删除它,否则它不会再次返回。也就是说,它们都“分配”了内存。

但是,new/还delete可以通过构造函数,析构函数和运算符重载来执行其他任意工作。malloc/ free仅分配和释放内存。

实际上,由于new具有足够的可自定义性,因此不必从堆中返回内存,甚至根本不必分配内存。但是默认值new是。


7

new和malloc之间的主要区别是new调用对象的构造函数,而delete的相应调用调用对象的析构函数。

还有其他区别:

  • new是类型安全的,malloc返回类型的对象void*

  • new在错误上引发异常,malloc返回NULL并设置errno

  • new是一个运算符,可以重载,malloc是一个函数,不能重载

  • new[],它分配数组,比起数组更直观和类型安全 malloc

  • malloc可以通过调整源分配的大小realloc,- new不能调整源分配的大小

  • malloc可以分配一个N字节的内存块,new必须要求分配一个char类型数组

查看差异,总结是malloc是C风格的,新的是C ++风格的。使用适合您的代码库的代码。

尽管使用不同的内存分配算法来实现new和malloc是合法的,但是在大多数系统上,新的内部是使用malloc实现的,不会产生系统级的差异。


5

有这几件事情new确实是malloc不:

  1. new 通过调用该对象的构造函数来构造该对象
  2. new 不需要类型转换分配的内存。
  3. 它不需要分配大量的内存,而是需要构造许多对象。

因此,如果使用malloc,则需要显式地执行上述操作,这并不总是可行的。此外,new可以重载但malloc不能重载。

总之,如果您使用C ++,请尝试使用new尽可能多的内容。


4

也,

全局的new和delete可以被覆盖,malloc / free不能。

每种类型可以覆盖更多的new和delete。


3

newdelete是C ++ 原语,它们声明一个类的新实例或将其删除(从而为该实例调用该类的析构函数)。

mallocfree是C 函数,它们分配和释放内存块(大小)。

两者都使用堆进行分配。malloc而且free它们仍然是“低级”,因为它们只是保留了一块可能与指针相关联的内存空间。在该内存周围不会创建任何结构(除非您将C数组视为结构)。


1
C ++中的new没有声明类的实例。它(通常)从堆中分配一个,并且不声明任何内容。您可以仅通过声明实例来声明实例,在这种情况下,实例将在堆栈中或在全局变量中,具体取决于声明的存储时间。
史蒂夫·杰索普

好吧,它为该类分配了内存空间,但是您不能在堆栈中“声明”一个类,而不是真正意义上将类存储在堆栈中。该声明仅涉及指向该类的指针,该类始终在堆栈中分配,而持有该类的实际内存在堆中。
豪尔赫·科尔多瓦

是的你可以。根据问题标签,这是C ++,因此对象可以进入堆栈。而new不是声明,而是表达式。声明和分配它们是分开的事情。
史蒂夫·杰索普

2

new和delete是c ++中的运算符;也可以超载。malloc和free是c中的函数;

当new抛出异常而失败时,malloc返回null ptr。

malloc返回的地址需要再次按类型转换,因为它返回(void *)malloc(size)New返回类型化的指针。


2
  • new是运算符,而malloc()是功能。
  • new返回确切的数据类型,而malloc()返回void *(void类型的指针)。
  • malloc(),不初始化内存,默认值是垃圾,而如果是new,则使用默认值初始化内存,如int则使用“零(0)”初始化。
  • delete和free()都可以用于'NULL'指针。

0
  • 要使用malloc(),我们需要在中包含 <stdlib.h>或 不需要<alloc.h>的程序new
  • new并且delete可以过载,但malloc不能过载。
  • 使用放置new,我们可以将地址传递到我们要分配内存的地方,但在情况下则无法实现malloc

1
alloc.h不是标准标头。<new>需要使用新的展示位置。
MM

0

此代码用于使用delete关键字或free函数。但是,当使用'malloc'或'new'创建指针对象并使用delete取消分配对象内存时,即使该对象指针也可以作为类中的调用函数。之后,使用free而不是delete,然后在free语句之后也可以工作,但是当同时使用free语句时,仅指针对象无法调用类中的函数。代码如下:

#include<iostream>


using namespace std;

class ABC{
public: ABC(){
    cout<<"Hello"<<endl;
  }

  void disp(){
    cout<<"Hi\n";
  }

};

int main(){

ABC* b=(ABC*)malloc(sizeof(ABC));
int* q = new int[20];
ABC *a=new ABC();
b->disp();

cout<<b<<endl;
free(b);
delete b;
//a=NULL;
b->disp();
ABC();
cout<<b;
return 0;
}

输出:

Hello
Hi
0x2abfef37cc20

-3

1. new syntex比malloc()更简单

2. new / delete是一个运算符,其中malloc()/ free()是一个函数。

3.new/delete比malloc()/ free()执行得更快,因为新的汇编代码直接由编译器粘贴。

4.我们可以在操作员叠加的帮助下更改程序中的新/删除含义。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.