wake-up-neo.com

C ++ new int [0] - reserviert es Speicher?

Eine einfache Test-App:

cout << new int[0] << endl;

ausgänge:

0x876c0b8

Es sieht also so aus, als würde es funktionieren. Was sagt der Standard dazu? Ist es immer legal, einen leeren Speicherblock "zuzuweisen"?

224
anon

Ab 5.3.4/7

Wenn der Wert des Ausdrucks in einem Direkt-Neu-Deklarator Null ist, wird die Zuweisungsfunktion aufgerufen, um ein Array ohne Elemente zuzuweisen.

Vom 3.7.3.1/2

Der Effekt der Dereferenzierung eines Zeigers, der als Anforderung für die Größe Null zurückgegeben wird, ist nicht definiert.

Ebenfalls

Auch wenn die Größe des angeforderten Speicherplatzes [von new] Null ist, kann die Anforderung fehlschlagen.

Das heißt, Sie können dies tun, aber Sie können den Speicher, den Sie erhalten, nicht legal (in einer genau definierten Weise auf allen Plattformen) dereferenzieren - Sie können ihn nur an Array delete übergeben - und Sie sollten ihn löschen.

Hier ist eine interessante Fußnote (d. H. Kein normativer Teil der Norm, sondern zu Auslagerungszwecken enthalten), die an den Satz aus 3.7.3.1/2 angehängt ist

[32. Der Operator new () soll durch Aufrufen von malloc () oder calloc () implementiert werden können, sodass die Regeln im Wesentlichen gleich sind. C++ unterscheidet sich von C darin, dass eine Null-Anforderung erforderlich ist, um einen Nicht-Null-Zeiger zurückzugeben.]

226
Faisal Vali

Ja, es ist legal, ein Array der Größe Null wie dieses zuzuweisen. Sie müssen es aber auch löschen.

21
anon

Was sagt der Standard dazu? Ist es immer legal, einen leeren Speicherblock "zuzuweisen"?

Jedes Objekt hat eine eindeutige Identität, d. H. Eine eindeutige Adresse, die eine Länge ungleich Null impliziert (die tatsächliche Speichermenge wird stillschweigend erhöht, wenn Sie nach Null Bytes fragen).

Wenn Sie mehr als eines dieser Objekte zugewiesen haben, werden Sie feststellen, dass sie unterschiedliche Adressen haben.

15
ChrisW

Ja, es ist völlig legal, einen Block mit der Größe 0 Mit new zuzuweisen. Sie können einfach nichts Nützliches damit anfangen, da Sie auf keine gültigen Daten zugreifen können. int[0] = 5; Ist illegal.

Ich glaube jedoch, dass der Standard Dinge wie malloc(0) zulässt, um NULL zurückzugeben.

Sie müssen immer noch den Zeiger delete [] Eingeben, den Sie ebenfalls von der Zuordnung erhalten.

14
Evan Teran

Kurioserweise erfordert C++, dass der Operator new einen legitimen Zeiger zurückgibt, selbst wenn null Bytes angefordert werden. (Das Erfordernis dieses seltsam klingenden Verhaltens vereinfacht Dinge an anderer Stelle in der Sprache.)

Ich fand Effective C++ Third Edition wie folgt in "Punkt 51: Konvention beim Schreiben und Löschen einhalten".

1
shuaihanhungry