Eine einfache Test-App:
cout << new int[0] << endl;
Ausgänge:
0x876c0b8
Es sieht also so aus, als ob es funktioniert. Was sagt der Standard dazu? Ist es immer legal, einen leeren Speicherblock "zuzuweisen"?
Eine einfache Test-App:
cout << new int[0] << endl;
Ausgänge:
0x876c0b8
Es sieht also so aus, als ob es funktioniert. Was sagt der Standard dazu? Ist es immer legal, einen leeren Speicherblock "zuzuweisen"?
Antworten:
Ab 5.3.4 / 7
Ab 3.7.3.1/2
Ebenfalls
Das bedeutet, dass Sie dies tun können, aber Sie können den Speicher, den Sie erhalten, nicht legal (auf alle Plattformen genau definiert) dereferenzieren - Sie können ihn nur an Array Delete übergeben - und Sie sollten ihn löschen.
Hier ist eine interessante Fußnote (dh kein normativer Teil des Standards, aber zu Expository-Zwecken enthalten), die dem Satz vom 3.7.3.1/2 beigefügt ist
quelle
new[]
mit a ausgleichendelete[]
- unabhängig von der Größe. Insbesondere wenn Sie anrufennew[i]
, benötigen Sie etwas mehr Speicher als den, den Sie zuweisen möchten, um die Größe des Arrays zu speichern (das späterdelete[]
bei der Freigabe verwendet wird)Ja, es ist legal, ein Array mit der Größe Null wie dieses zuzuweisen. Sie müssen es aber auch löschen.
quelle
int ar[0];
das illegal ist, warum ist neues OK?sizeof (type)
wird erwartet, dass es niemals Null zurückgibt. Siehe zum Beispiel: stackoverflow.com/questions/2632021/can-sizeof-return-0-zeroJedes Objekt hat eine eindeutige Identität, dh eine eindeutige Adresse, die eine Länge ungleich Null impliziert (die tatsächliche Speichermenge wird stillschweigend erhöht, wenn Sie nach null Byte fragen).
Wenn Sie mehr als eines dieser Objekte zugewiesen haben, werden sie unterschiedliche Adressen haben.
quelle
operator []
speichert auch die Größe des Arrays irgendwo (siehe isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array ). Wenn die Implementierung den Daten also die Byteanzahl zuweist, kann sie nur die Byteanzahl und 0 Bytes für die Daten zuweisen und einen 1-nach-letzten-Zeiger zurückgeben.operator new[]
unterschiedliche Zeiger zurückgeben sollen. BTW, dasnew expression
hat einige zusätzliche Regeln (5.3.4). Ich konnte keine Ahnung finden , dienew
mit 0 Größe tatsächlich benötigt etwas zu vergeben. Entschuldigung, ich habe abgelehnt, weil ich finde, dass Ihre Antwort nicht die Fragen beantwortet, sondern einige kontroverse Aussagen enthält.new[]
Implementierung Adressen in einem Bereichwhile(!exitRequested) { char *p = new char[0]; delete [] p; }
Schleife ohne Recycling von Zeigern ausführt, in Staub zerfällt, bevor ihm möglicherweise der Adressraum ausgeht. Auf einer Plattform mit 32-Bit-Zeigern wäre dies jedoch ein weit weniger vernünftige Annahme.Ja, es ist völlig legal, einen
0
Block mit Größe zuzuweisennew
. Sie können damit einfach nichts Nützliches anfangen, da Sie keine gültigen Daten haben, auf die Sie zugreifen können.int[0] = 5;
ist illegal.Ich glaube jedoch, dass der Standard Dinge wie
malloc(0)
die Rückkehr zulässtNULL
.Sie benötigen weiterhin den
delete []
Zeiger, den Sie von der Zuordnung erhalten.quelle
Ich fand, dass Effective C ++ Third Edition in "Punkt 51: Konvention beim Schreiben von Neuem und Löschen einhalten".
quelle
Ich garantiere Ihnen, dass new int [0] Sie zusätzlichen Speicherplatz kostet, da ich es getestet habe.
Zum Beispiel die Speichernutzung von
ist deutlich kleiner als
Die Speichernutzung des zweiten Code-Snippets minus der des ersten Code-Snippets ist der Speicher, der für die zahlreichen neuen int [0] verwendet wird.
quelle