2010-05-15 1 views

Antwort

32

Es gibt keine new/delete Expression in C.

Die Äquivalente sind die malloc and free functions, wenn Sie die Konstrukteure/Destruktoren und Typsicherheit zu ignorieren.

#include <stdlib.h> 

int* p = malloc(sizeof(*p)); // int* p = new int; 
... 
free(p);      // delete p; 

int* a = malloc(12*sizeof(*a)); // int* a = new int[12]; 
... 
free(a);       // delete[] a; 
+2

* @ KennyTM: * Deferenziert 'sizeof (* p)' '' 'oder ist es vollständig äquivalent zum Schreiben' sizeof (int) '? Es scheint, dass im ersten Fall dieser Ausdruck möglicherweise einen Segmentierungsfehler verursacht (weil "p" zu diesem Zeitpunkt noch nicht zugewiesen ist). Im letzteren Fall würde ich wahrscheinlich immer noch "sizeof (int)" schreiben, weil es weniger Möglichkeiten gibt, das, was diese Aussage tut, falsch zu verstehen. – stakx

+5

@stakx: Der Operator 'sizeof' wird zur Kompilierzeit ausgewertet. Es gibt keine Dereferenzierung. 'sizeof (* p)' wird gegenüber 'sizeof (int)' bevorzugt, da der Compiler Sie nicht vor Größenabweichungen warnen kann, wenn Sie den Typ von 'p' in' double' ändern. – kennytm

+8

@stakx Der Operator 'sizeof' ist eine Zuordnung von ** type ** zu' size_t'. Der ** Wert ** seines Operanden ist überhaupt nicht interessant. Zum Beispiel, in 'sizeof (1 + 2)', gibt es absolut keine Notwendigkeit, das Ergebnis '3' zu berechnen. Der Operator 'sizeof' sieht einfach einen Ausdruck vom Typ' int + int' und folgert, dass das Ergebnis auch ein 'int' ist. Dann wird "int" auf 4 (oder 2 oder 8, abhängig von der Plattform) abgebildet. Das gleiche gilt für "sizeof (* p)". Das Typsystem weiß, dass die Dereferenzierung eines 'int *' auf der Typ-Ebene ein 'int' ergibt. 'sizeof' interessiert sich überhaupt nicht für den Wert von' * p', nur der Typ ist wichtig. – fredoverflow

3

Nicht direkt eine exakte Replik, aber kompatible Äquivalente sind malloc und frei.

<data-type>* variable = (<data-type> *) malloc(memory-size); 
free(variable); 

Keine Bauer/Destruktoren - C hat sowieso nicht sie :)

die Speicher-Größe zu erhalten, Sie sizeof Betreiber nutzen können.

Wenn Sie mit mehrdimensionalen Arrays arbeiten möchten, müssen Sie es mehrmals verwenden (wie neu):

int** ptr_to_ptr = (int **) malloc(12 * sizeof(int *)); //assuming an array with length 12. 
ptr[0] = (int *) malloc(10 * sizeof(int)); //1st element is an array of 10 items 
ptr[1] = (int *) malloc(5 * sizeof(int)); //2nd element an array of 5 elements etc 
+4

In C müssen Sie nicht von void * auf andere Zeiger umwandeln. Es ist nur int * p = malloc (sizeof (int) * cElements); –

+0

Chris: Bist du sicher? Ich habe seit einiger Zeit nicht mehr mit C gearbeitet, aber IIRC, ich musste es machen, weil der Rückgabetyp von malloc ungültig ist *. –

+0

In c 'void *' wird automatisch in andere Zeigertypen konvertiert. Die Rückgabe von malloc kann zu Fehlern führen, wenn Sie 'stdlib.h' nicht eingeschlossen haben, da die Parameter als 'int' angenommen wurden. –

2

Verwenden malloc/free-Funktionen.

6

Beachten Sie, dass Konstruktoren in C++ Ausnahmen auslösen können. Das Äquivalent von player* p = new player(); würde

so etwas wie dies in C sein
struct player *p = malloc(sizeof *p); 
if (!p) handle_out_of_memory(); 
int err = construct_player(p); 
if (err) 
{ 
    free(p); 
    handle_constructor_error(); 
} 

Das Äquivalent delete p ist einfacher, weil Destruktoren sollte nie „werfen“.

destruct(p); 
free(p); 
+0

Wie würde 'construct_player' aussehen? –

5

Verwendung von new und delete in C++ kombiniert zwei Verantwortung - Zuweisen/Freigeben dynamischen Speichers und Initialisieren/Freigeben eines Objekts.

Wie alle anderen Antworten sagen, ist die gebräuchlichste Art, dynamischen Speicher zuzuweisen und freizugeben, malloc und free. Sie können auch OS-spezifische Funktionen verwenden, um einen großen Teil des Speichers zu erhalten und Ihre Objekte zuzuordnen, aber das ist seltener - nur wenn Sie ziemlich spezifische Anforderungen haben, die malloc nicht erfüllt. In C stellen die meisten APIs ein Paar Funktionen bereit, die die anderen Rollen new und delete erfüllen.

Zum Beispiel verwendet die Datei api ein Paar öffnen und schließen Funktionen:

// C++ 
fstream* fp = new fstream("c:\\test.txt", "r"); 
delete fp; 

// C 
FILE *fp=fopen("c:\\test.txt", "r"); 
fclose(fp); 

Es kann sein, dass fopenmalloc verwendet den Speicher für die FILE Struktur zuzuordnen, oder es kann eine Tabelle für statisch zuweisen die maximale Anzahl von Dateizeigern beim Prozessstart. Der Punkt ist, die API erfordert nicht, dass der Client malloc und free verwendet.

andere APIs bieten Funktionen, die nur die Initialisierung durchführen und Loslassen Teil des Vertrages - das entspricht den Konstruktor und destructor, die der Client-Code ermöglicht, entweder automatisch, statische oder dynamische Speicher zu verwenden.Ein Beispiel ist die pThreads API:

pthread_t thread; 

pthread_create(&thread, NULL, thread_function, (void*) param); 

Dies ist der Kunde mehr Flexibilität ermöglicht, erhöht jedoch die Kopplung zwischen der Bibliothek und dem Client - der Kunde muss die Größe des pthread_t Typs kennen, während, wenn die Bibliothek beiden Griffe Zuweisung und Initialisierung Der Client muss die Größe des Typs nicht kennen, daher kann die Implementierung variieren, ohne den Client zu ändern. Weder führt so viel Kopplung zwischen dem Client und der Implementierung wie C++ ein. (Es ist oft besser, C++ als Metaprogrammierungssprache für Templates mit Vtables zu betrachten als eine OO-Sprache)

+0

Können Sie genau erklären, welche spezifischen Anforderungen malloc nicht erfüllt? – Pacerier

+0

@Pacerier 'malloc' weist Speicher zu. 'operator new' reserviert (normalerweise) Speicher * und * initialisiert den Speicher, um Werte zu enthalten, die vom Konstruktor der spezifizierten Objektklasse geliefert werden. (Es gibt eine Variable von 'operator new' namens 'placement new', die keinen Speicher reserviert, so dass Sie malloc für den ersten Teil und neu für den zweiten Teil verwenden können, wenn Sie dies wünschen) –