Was ist der Unterschied zwischen new / delete und malloc / free?

Antworten:

465

neu / löschen

  • Speicher zuordnen / freigeben
    1. Speicher aus 'Free Store' zugewiesen
    2. Gibt einen vollständig eingegebenen Zeiger zurück.
    3. new (Standardversion) gibt niemals NULL zurück (wird bei einem Fehler ausgelöst)
    4. Werden mit Type-ID aufgerufen (Compiler berechnet die Größe)
    5. Hat eine Version, die explizit Arrays behandelt.
    6. Die Neuzuweisung (um mehr Speicherplatz zu erhalten) wird (aufgrund des Kopierkonstruktors) nicht intuitiv gehandhabt.
    7. Ob sie malloc / free aufrufen, ist in der Implementierung definiert.
    8. Kann einen neuen Speicherzuweiser hinzufügen, um mit wenig Speicher umzugehen (set_new_handler)
    9. Operator neu / löschen kann legal überschrieben werden
    10. Konstruktor / Destruktor zum Initialisieren / Zerstören des Objekts

malloc / frei

  • Ordnet Speicher zu / gibt ihn frei
    1. Von 'Heap' zugewiesener Speicher
    2. Gibt eine Leere zurück *
    3. Gibt bei einem Fehler NULL zurück
    4. Muss die erforderliche Größe in Bytes angeben.
    5. Das Zuweisen eines Arrays erfordert eine manuelle Berechnung des Speicherplatzes.
    6. Einfache Neuzuweisung eines größeren Speicherbereichs (kein Kopierkonstruktor, über den Sie sich Sorgen machen müssen)
    7. Sie werden NICHT new / delete aufrufen
    8. Keine Möglichkeit, Benutzercode in die Zuordnungssequenz zu integrieren, um bei geringem Arbeitsspeicher zu helfen.
    9. malloc / free kann NICHT legal überschrieben werden

Tabellenvergleich der Funktionen:

 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                            

Technisch gesehen stammt der von new zugewiesene Speicher aus dem 'Free Store', während der von malloc zugewiesene Speicher aus dem 'Heap' stammt. Ob diese beiden Bereiche gleich sind, ist ein Implementierungsdetail. Dies ist ein weiterer Grund, warum malloc und new nicht gemischt werden können.

Martin York
quelle
12
Kann jemand etwas bearbeiten, um den "Free Store" im Gegensatz zum Heap zu erläutern? Ein Prozesshaufen ist ein bekanntes sprachunabhängiges (?) Konzept auf Betriebssystemebene. Woher kommt der "Free Store"?
Einpoklum
1
@einpoklum: Sie sind nur Namen von Speicherbereichen. Weder hat etwas mit dem als "Heap" bekannten Sprachkonzept noch mit dem OS-Konzept von "Process Heap" zu tun. C ++ ist bewusst als Platform / OS / Compiler-neutral definiert. Die Verwendung eines bestimmten Betriebssystemkonzepts wie "Prozesshaufen" würde also die Flexibilität des Standards untergraben.
Martin York
4
@winterlight: Das stimmte früher, aber nicht mehr. Siehe: linux.die.net/man/3/free If ptr is NULL, no operation is performed.
Martin York
2
@LokiAstari Es sieht so aus, als wären 'Heap', 'Free Store' und 'Dynamic Memory / Storage' Synonyme: In Bjarne Stroustrups A Tour of C ++ sagt er: "Der newOperator weist Speicher aus dem Free Store zu (auch als dynamischer Speicher bekannt) und Heap ) . Der C ++ 14 Standard Abschnitt 3.7.4 auf Dynamic Storage sagt "Objekte können dynamisch während der Programmausführung (1.9) erstellt werden, neue Ausdrücke (5.3.4), und vernichteten mit Lösch-Ausdrücke."
Max Heiber
2
@mheiber: Es bedeutet, dass sie gleich sein können. Und mehrere Implementierungen implementieren neue durch Aufrufen von malloc (beachten Sie, dass das Umkehren ausdrücklich nicht zulässig ist). Mehrere Implementierungen halten diese Speicherbereiche jedoch vollständig getrennt. Der Grund, warum sie auch getrennt gehalten wurden, ist, dass dadurch der C ++ - Speicherverwaltungscode auf andere Weise als bei der C-Speicherverwaltung optimiert werden kann. Der Punkt ist: Sie könnten gleich sein, aber Sie können nicht davon ausgehen, dass sie es sind.
Martin York
81

Der relevanteste Unterschied besteht darin, dass der newOperator Speicher zuweist, dann den Konstruktor deleteaufruft und den Destruktor aufruft und dann den Speicher freigibt.

Falle
quelle
22
Genau genommen weist der neue Operator nur den Speicher zu. Es ist der neue Ausdruck, der den neuen Operator aufruft und dann den Konstruktor im zugewiesenen Speicher ausführt.
Don Wakefield
Ein weiterer Unterschied besteht darin, wo der Speicher zugewiesen wird. Ich habe kürzlich irgendwo gesehen, dass malloc / free auf dem Heap operiert, während new / delete in einem anderen Speicherbereich operiert, dessen Name mir jetzt entgeht. (Es genügt jedoch zu sagen, dass ein anderer Bereich wahrscheinlich als ein weiterer Haufen angesehen werden kann.)
RobH
2
@mgb: Ja, Sie haben Recht, dass Objekte entweder auf dem "Anwendungsheap" oder dem Stapel zugewiesen werden. Aber @RobH bezieht sich auf das, was der Standard verschiedene Teile des "Application Heap" nennt. Es gibt den "Heap", von dem aus malloc Speicher zuweist, und den "Free Store", von dem new Speicher zuweist. In einigen Implementierungen überschneiden sich diese Bereiche jedoch (dies ist ein Implementierungsdetail).
Martin York
1
Ihre Aussage ist zu 100% richtig, beantwortet aber die gestellte Frage einfach nicht. Siehe die Antwort unten. Es gibt einen Grund, warum sie mehr Stimmen hat als Ihre.
Murali
1
Ich wollte nur sagen, dass malloc / free zumindest erwähnt werden sollte, damit es sich um einen Vergleich handelt, auf den Ihre Antwort fehlte. Trotzdem ist es eine relevante und genaue Aussage, also hoffe ich, dass Sie meinen Standpunkt verstehen. Wie auch immer, wenn nur SO mir erlauben würde, meine Ablehnung zurückzunehmen, würde ich es von ganzem Herzen tun.
Murali
30

newruft den ctor des Objekts auf, deleteruft den dtor auf.

malloc& freeeinfach Rohspeicher zuweisen und freigeben.

James Curran
quelle
Was meinst du mit rohem Gedächtnis?
Zerstörer
3
Rohe Erinnerung hat nichts damit zu tun. Es wurde noch kein Objekt darin konstruiert, nichts wurde darin kopiert, und in den meisten Fällen wurde der vorherige Inhalt nicht überschrieben.
James Curran
14

new/ deleteist C ++, malloc/ freestammt aus dem guten alten C.

Ruft in C ++ neweinen Objektkonstruktor und deleteden Destruktor auf.

mallocund free, aus den dunklen Zeiten vor OO kommend, ordne nur den Speicher zu und gebe ihn frei, ohne irgendeinen Code des Objekts auszuführen.

Treb
quelle
9
"Aus dem dunklen Zeitalter vor OO kommen" klingt so, als würden Sie implizieren, dass Neu / Löschen besser als Malloc / Frei sind, wenn es in Wirklichkeit weder besser noch schlechter ist, sondern nur unterschiedliche Verwendungszwecke haben. Beachten Sie, dass ich nicht derjenige bin, der Sie herabgestimmt hat, ich vermute nur.
Graeme Perrow
13

Rufen Sie in C ++ new/ deleteden Konstruktor / Destruktor entsprechend auf.

malloc/ freeEinfach - Speicher aus dem Heap zuzuteilen. new/ deleteordne auch Speicher zu.

Verschlüsseln
quelle
10

Die einzigen Ähnlichkeiten bestehen darin, dass malloc/ newbeide einen Zeiger zurückgeben, der einen bestimmten Speicher auf dem Heap adressiert, und beide garantieren, dass ein solcher Speicherblock nach seiner Rückgabe erst wieder zurückgegeben wird, wenn Sie ihn zuerst freigeben / löschen. Das heißt, beide "reservieren" Speicher.

Allerdings new/ deleteführen beliebige andere Arbeiten zusätzlich über den Bau, Destruktoren und Betreiber Überlastung. malloc/ freenur immer Speicher zuweisen und freigeben.

Tatsächlich newist es ausreichend anpassbar, dass es nicht unbedingt Speicher vom Heap zurückgibt oder überhaupt Speicher zuweist. Die Standardeinstellung newgilt jedoch.

Steve Jessop
quelle
7

Der Hauptunterschied zwischen new und malloc besteht darin, dass new den Konstruktor des Objekts aufruft und der entsprechende Aufruf zum Löschen den Destruktor des Objekts aufruft.

Es gibt andere Unterschiede:

  • newist typsicher und mallocgibt Objekte vom Typ zurückvoid*

  • newlöst bei einem Fehler eine Ausnahme aus, gibt malloczurück NULLund setzt errno

  • newist ein Operator und kann überladen werden, mallocist eine Funktion und kann nicht überladen werden

  • new[], das Arrays zuweist, ist intuitiver und typsicherer als malloc

  • malloc-derivierte Zuordnungen können über geändert werden realloc. new-derivierte Zuordnungen können nicht in der Größe geändert werden

  • mallockann einen N-Byte-Speicherblock newzuweisen , muss aufgefordert werden, ein Array von beispielsweise charTypen zuzuweisen

Wenn man die Unterschiede betrachtet, ist eine Zusammenfassung: malloc ist C-esque, neu ist C ++ - esque. Verwenden Sie diejenige, die sich für Ihre Codebasis richtig anfühlt.

Obwohl es legal ist, dass new und malloc mit unterschiedlichen Speicherzuweisungsalgorithmen implementiert werden, wird new auf den meisten Systemen intern mit malloc implementiert, was keinen Unterschied auf Systemebene ergibt.

Walter
quelle
5

Es gibt ein paar Dinge, die newdas mallocnicht tun:

  1. new Konstruiert das Objekt durch Aufrufen des Konstruktors dieses Objekts
  2. new erfordert keine Typumwandlung des zugewiesenen Speichers.
  3. Es muss nicht genügend Speicher zugewiesen werden, sondern es müssen mehrere Objekte erstellt werden.

Wenn Sie also verwenden malloc, müssen Sie die oben genannten Dinge explizit ausführen, was nicht immer praktisch ist. Darüber hinaus newkann überlastet werden, mallockann aber nicht sein.

Kurz gesagt, wenn Sie C ++ verwenden, versuchen Sie, newso viel wie möglich zu verwenden.

herohuyongtao
quelle
4

ebenfalls,

Das globale Neu und Löschen kann überschrieben werden, malloc / free nicht.

Weitere Neuheiten und Löschvorgänge können pro Typ überschrieben werden.

DanJ
quelle
3

newund deletesind C ++ - Grundelemente, die eine neue Instanz einer Klasse deklarieren oder löschen (wodurch der Destruktor der Klasse für die Instanz aufgerufen wird).

mallocund freesind C- Funktionen und sie ordnen Speicherblöcke (in der Größe) zu und geben sie frei.

Beide verwenden den Heap, um die Zuordnung vorzunehmen. mallocund freesind dennoch "niedriger", da sie nur einen Teil des Speicherplatzes reservieren, der wahrscheinlich einem Zeiger zugeordnet wird. Um diesen Speicher herum werden keine Strukturen erstellt (es sei denn, Sie betrachten ein C-Array als Struktur).

Jorge Córdoba
quelle
1
new in C ++ deklariert keine Instanz einer Klasse. Es ordnet (normalerweise) einen vom Heap zu und deklariert nichts. Sie können eine Instanz deklarieren, indem Sie sie deklarieren. In diesem Fall befindet sie sich je nach Speicherdauer der Deklaration auf dem Stapel oder in globalen Formaten.
Steve Jessop
Nun, es reserviert den Speicherplatz für die Klasse, aber Sie können eine Klasse im Stapel nicht "deklarieren", nicht im eigentlichen Sinne, die Klasse im Stapel zu speichern. Die Deklaration enthält nur den Zeiger auf die Klasse, die immer im Stapel zugeordnet ist. Der tatsächliche Speicher, in dem sich die Klasse befindet, befindet sich im Heap.
Jorge Córdoba
Ja, du kannst. Laut den Frage-Tags ist dies C ++, sodass Objekte auf dem Stapel abgelegt werden können. Und neu ist keine Erklärung, es ist ein Ausdruck. Etwas zu deklarieren und zuzuweisen sind getrennte Dinge.
Steve Jessop
2

new und delete sind Operatoren in c ++; was auch überlastet werden kann. malloc und free sind Funktion in c;

malloc gibt null ptr zurück, wenn ein Fehler auftritt, während new eine Ausnahme auslöst.

Die von malloc zurückgegebene Adresse muss vom Typ erneut umgewandelt werden, da sie den (void *) malloc (size) New zurückgibt. Geben Sie den eingegebenen Zeiger zurück.

VishalTiwari
quelle
2
  • new ist ein Operator, während malloc () eine Funktion ist.
  • new gibt den genauen Datentyp zurück, während malloc () void * (Zeiger vom Typ void) zurückgibt.
  • malloc (), Speicher wird nicht initialisiert und der Standardwert ist Garbage, während im Falle eines neuen Speichers der Speicher mit dem Standardwert initialisiert wird, wie bei 'zero (0)' im Fall von int.
  • delete und free () können beide für 'NULL'-Zeiger verwendet werden.
Anurag Singh
quelle
0
  • So verwenden Sie die malloc(), müssen wir schließen <stdlib.h> oder <alloc.h>im Programm , die nicht für erforderlich new.
  • newund deletekann überlastet werden, mallockann aber nicht.
  • Mit der Platzierung newkönnen wir die Adresse übergeben, an die wir Speicher zuweisen möchten, dies ist jedoch im Fall von nicht möglich malloc.
Ron Davis
quelle
1
alloc.hist kein Standardheader. <new>ist erforderlich, um Platzierung neu zu verwenden.
MM
0

Dieser Code zur Verwendung des Schlüsselworts delete oder der freien Funktion. Wenn Sie jedoch ein Zeigerobjekt mit 'malloc' oder 'new' erstellen und den Objektspeicher mit delete freigeben, kann auch dieser Objektzeiger eine Aufruffunktion in der Klasse sein. Danach benutze free statt delete, dann funktioniert es auch nach der free-Anweisung, aber wenn beide verwendet werden, kann nur das Zeigerobjekt nicht aufrufen, um in der Klasse zu funktionieren. Der Code lautet wie folgt:

#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;
}

Ausgabe :

Hello
Hi
0x2abfef37cc20
Chirag Kadam
quelle
-3

1.new syntex ist einfacher als malloc ()

2.new/delete ist ein Operator, bei dem malloc () / free () eine Funktion ist.

3.new/delete wird schneller ausgeführt als malloc () / free (), da neuer Assemly-Code direkt vom Compiler eingefügt wird.

4. Wir können die Bedeutung von Neu / Löschen im Programm mit Hilfe der Operatorüberladung ändern.

Nitesh
quelle