Ist delete[] gleich löschen?
IP_ADAPTER_INFO *ptr=new IP_ADAPTER_INFO[100];
wenn ich kostenlos mit
delete ptr;
wird es zu Speicherverlust führen, wenn nicht, dann warum ?
Dies ist disassembly-code generiert VS2005
; delete ptr;
0041351D mov eax,dword ptr [ptr]
00413520 mov dword ptr [ebp-0ECh],eax
00413526 mov ecx,dword ptr [ebp-0ECh]
0041352C push ecx
0041352D call operator delete (4111DBh)
00413532 add esp,4
; delete []ptr;
00413535 mov eax,dword ptr [ptr]
00413538 mov dword ptr [ebp-0E0h],eax
0041353E mov ecx,dword ptr [ebp-0E0h]
00413544 push ecx
00413545 call operator delete[] (4111E5h)
0041354A add esp,4
- Was haben die docs gesagt?
- ich habe gelesen , dass der Destruktor aufgerufen wird, werden für das erste element im array, sondern ganze Speicher wird freigegeben, gleiche ich sehe beim Debuggen
- Nein, nur das erste element wird freigegeben, andere nicht.
- Nein, das ist nicht sicher. Kann es passieren, dass Weg, aber dann ist es vielleicht nicht. Für Hülsen, es ist sogar wahrscheinlich, dass es vielleicht nicht. Aber man weiß ja nie.
- Was wird passieren, wenn
IP_ADAPTER_INFO
aufhört zu POD-Typ? Wollen Sie Bearbeiten den code? Sie versehen Ihre Frage mit C++ tag, so sollten Sie überlegen, mitstd::vector
. - Ich empfehle das ignorieren dieser Frage und statt zu Lesen [delete vs delete[]](stackoverflow.com/questions/4255598/delete-vs-delete) statt, deren Antworten sind viel mehr auf den Punkt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ob dies führt zu einem Speicherverlust, wischt Ihrer Festplatte, wird Sie Schwanger, macht fiesen Nasen-Dämonen, die Sie jagen rund um Ihre Wohnung, oder lässt alles funktionieren ohne erkennbare Probleme, ist nicht definiert. Könnte es so sein mit einem compiler, und ändern Sie mit einem anderen, ändern sich mit einer neuen compiler-version, mit jeder neuen Zusammenstellung, mit den Mond-Phasen, Ihrer Stimmung, oder je nach der Anzahl der neutrinos, die durch die übergebene Prozessor auf dem letzten, sonnigen Nachmittag. Oder ist es vielleicht nicht.
All das und unendlich viele andere Möglichkeiten sind in einem Begriff: Undefiniertes Verhalten:
Nur bleiben Weg von es.
delete
unddelete[]
verhält sich in einigen spezifischen Implementierung gibt nur die falsche Idee. Es ist Undefiniertes Verhalten: tun Sie es nicht.Nur eine Darstellung von etwas "Undefiniertes" Verhalten auf bestimmte Betriebssysteme und Compiler. Hoffe, es könnte hilfreich sein für die Menschen, um Ihren code Debuggen.
Test 1
Test 2
Test 3
Test 4
Test 1
Test 2
Test 3
Test 4
Test 1
Test 2
Test 3
Test 4
Test 1
Test 2
Test 3
Test 4
Wird es in der Regel nicht Auslaufen, weil im Fall von POD-Destruktoren sind trivial und es gibt keine Notwendigkeit für den Aufruf des von Ihnen so
delete
nur freigibt belegte Speicher durch das array. Memory-deallocation-benötigt nur einen Zeiger-Wert, so wird es zurück auf den Haufen. Das array accopies einen zusammenhängenden block von Speicher und damit die Freigabe kann erfolgreich nur als wenn es eine Freigabe von einem einzigen element.Aber verlassen Sie sich nicht auf dieses, da es ist Undefiniertes Verhalten. Vielleicht funktioniert es in Ordnung, vielleicht etwas schreckliches passiert, arbeiten am compiler, nicht am anderen, und viele Menschen danken Ihnen für das Einpflanzen einen Fehler.
Sehen diese Antwort für details.
new T[]
können hinzufügen, einsizeof
offset-unabhängig von der POD-ness von T, in welchem Falldelete[]
wird dies kompensieren.delete
würde der header-block Zuweisung von ein paar bytes, die Interpretation einer (möglicherweise nicht initialisierten) element Anzahl als header und verursachen unvorhersehbare heap-Beschädigung. Was natürlich zeigt sich erst, wenn der boss das sieht.struct A { void operator delete[](void *p, size_t t) { } };
obwohlstruct A
ist einPOD
,new A[10]
ordnen und zu speichern, die Größe und diedelete[]
haben, um es abzurufen und es passieren Betreiber löschenlöschen :
ruft die entsprechende Destruktor nur für das element hingewiesen (falls erforderlich),
dann gibt den Speicher chunk
delete[] :
ruft die entsprechende Destruktor für jedes element in seiner Reihe (falls erforderlich),
dann gibt den Speicher chunk
delete
unddelete[]
korrekt verwendet werden. Diese Frage ist insbesondere etwa der Fall, wenndelete
wird dort verwendet, wodelete[]
hätte.Wenn Einem Punkte für ein array reserviert wurde über new T[n], dann müssen Sie es löschen per delete[] A.
Warum?
Den Unterschied zwischen delete und delete[] ist einfach - der ehemalige zerstört ein Skalar-Objekt und die letztere zerstört ein array.
Mehr info hier und hier.
UPDATE 1 (falsch):
Wenn Sie mit delete (und nicht mit delete []), während die Zuweisung mit new T[n], nur das erste element wird freigegeben, während andere nicht sind destructorized, das führt zu Speicherverlust. Warum? Dies ist der Weg, Bjarne Stroustrup, und andere entworfen hatte, die Sprache. Und es ist nicht compiler-Variation. Wenn ein compiler plant den anderen Weg, es ist nur nicht nach dem standard. Die Programmiersprache C++ , Kapitel 6.2.6.2 und 19.4.5.
UPDATE 2 (richtig):
Ich bin zuzugeben, mein Fehler, über das Verhalten der Verwendung der delete-operator für Allokationen mit new T[n]. Lesen Sie das erwähnte Dokument finde ich nicht die genaue Beschreibung, so dass ich vermute, in dieser situation das Verhalten wird undefined und variiert von compiler zu compiler. AFAIK, MSVC-compiler zum Beispiel erzeugt anderen code als der GCC. Bitte ignorieren Sie UPDATE 1.
Array von POD es wird nicht Leck (mit den meisten Compilern). Zum Beispiel, MSVC generiert identisch code für löschen und delete[] für array POD.
Persönlich, ich denke, dass C/C++ könnte ohne operator delete[]. Compiler kennt die Größe des Objekts und den zugeordneten Speicher-Größe ist zur Laufzeit bekannt, so ist es sehr einfach zu wissen, ist ein Zeiger-array ist oder nicht und entsorgen Sie den Speicher in einem richtigen Weg.
EDIT:
OK, Jungs. Können Sie test in Ihre compiler-und sagen, ob es ein Leck?
Versuchen zu denken, da ein compiler-Entwickler. Wir haben neue, new[], löschen, delete[]. Jeder neue hat seine eigene löschen. Scheint perfekt und vollständig. Mal sehen, was passiert, wenn Sie anrufen delete[]?
Was ist ein Destruktor für POD? Nichts!
Also, Aufruf löschen für array POD wird nicht undicht!!! Auch wenn es Pausen der standard. Auch wenn es nicht empfohlen wird.
EDIT2:
Dies ist disassembly-code generiert von VS2008:
delete[]
ist definitiv nicht eine form der Optimierung. Es geht um Richtigkeit.