Ich habe Thema gelesen Calling delete on variable allocated on the stack Und ich weiß, wenn Benutzer im Stapel löschen, siehe Fehler. Aber ich möchte mehr und tiefere Informationen wissen. Warum Fehler?Warum Zeiger auf Stapel löschen ist ein Fehler?
Antwort
Stapel erstellten Objekte sind automatische während nicht-Stack erzeugten Objekte (mit dem Schlüsselwort new
) sind dynamische und müssen das Schlüsselwort delete
aufgearbeiteten werden.
Objekte auf dem Stapel werden durch das System automatisch einen aufgearbeiteten anderen Mechanismus auf Objekte dynamisch Schlüsselwort zugeordnet Verwendung new
.
So Stichwort Aufruf delete
mit einer Objektadresse, der nicht dynamisch mit dem Schlüsselwort new
verursachen Probleme gebunden zugeordnet wurde.
Begraben (nicht sehr tief) in den C++ - Laufzeitbibliotheken ist eine Datenstruktur, die als Heap bezeichnet wird. Der Heap-Job (konzeptionell sowieso) besteht darin, mit einem riesigen Array von Bytes zu beginnen und Teile dieses Arrays zu Ihrem Programm zu übertragen, wenn Ihr Programm danach fragt. Auf diese Weise müssen Sie selbst keinen Chunk-Management-Code implementieren (was gut ist, weil die korrekte und effiziente Handhabung in allen Fällen eine nicht-triviale Codierungsaufgabe ist).
Immer wenn Ihr Programm den Operator new
aufruft, trennt ein Aufruf des Heap-Codes einen Teil dieses Arrays (ebenfalls konzeptionell) und übergibt es an Ihr Programm. Umgekehrt, wenn Sie später den Operator delete
aufrufen, wird dieses Sub-Array von Bytes an den Heap zurückgegeben, wobei der Code des Heaps es wieder zusammen mit seinen benachbarten Abschnitten eines großen Arrays zusammenführen kann (wenn einer oder beide der benachbarten Abschnitte auch sind) verfügbar sein) oder zumindest die Verfügbarkeit aufzeichnen, damit sie später über einen nachfolgenden Aufruf an new
wieder verwendet werden kann.
Objekte auf dem Stapel befinden sich jedoch nicht innerhalb des riesigen Arrays des Heaps; Sie befinden sich vielmehr auf dem Stapel. Wenn Sie also delete
für ein Stack-Objekt aufrufen, übergeben Sie dem Heap ein Speicherstück, das nie Teil seines Ressourcen-Pools war. Die C++ - Sprachdesigner hätten verlangen können, dass jede Heap-Implementierung nach dieser Bedingung sucht und eine vorhersehbare Reaktion ausführt (z. B. einfach den unbekannten Zeiger ignoriert oder eine Fehlermeldung ausgibt oder einen Assertionsfehler auslöst und das Programm beendet), aber dies tut Ein solcher Check für jede delete
könnte ineffizient sein, und die C++ - Sprache priorisiert die Dinge so effizient wie möglich zur Laufzeit. Daher wird durch die Übergabe eines Zeigers an delete
, der zuvor nicht von new
zurückgegeben wurde, undefined Verhalten, was bedeutet, dass der Designer der C++ - Laufzeitbibliothek nicht kümmern muss, was sein Heap-Code in dieser Situation tun wird, da diese Situation nie passieren in erster Linie - es wird nur passieren, wenn Sie einen Programmierfehler gemacht haben. Also, machen Sie diesen Fehler nicht, weil es Ihr Programm dazu bringt, sich so zu verhalten, wie Sie es nicht wollten.
Um es richtig zu verstehen, sollten Sie zuerst verstehen, was Stapel ist und was Haufen bedeuten. Gehen Sie durch this, um zu verstehen, wie Prozessspeicher ausgerichtet ist.
Wenn Sie eine Funktion aufrufen, empfängt sie zusammenhängende Speicherblöcke aus dem virtuellen Kern des Prozesses. die es verwendet, um Argumente zu empfangen, lokale Variablen zu definieren und Absenderadresse usw. zu speichern. Dieser Speicher wird freigegeben, sobald die Funktion ihre Ausführung beendet und zurückkehrt. Dies nennt man Stapel.
Wo die Heap-Zuweisung zur Laufzeit erfolgt. und daher ist es nicht garantiert, dass sie zusammenhängend sind. new
Funktionsaufruf findet geeigneten Speicherblock für Sie aus dem freien Pool und löscht es zurück in den freien Speicherpool.
Da Stack und Heap physikalisch unterschiedliche Entitäten sind, sollten auf Heap definierte Operationen nicht auf dem Stack ausgeführt werden, da dies zur Laufzeit undefiniertes Verhalten zur Folge hat, wie von Jeremy Friesner erläutert. Als Faustregel ist es besser, Fehler so früh wie möglich zu melden, und genau das tut der Compiler, wenn er ein gefundenes Objekt findet, das auf dem Stapel definiert wurde.
Ein hilfreicher Compiler kann den Fehler melden, aber es ist nicht erforderlich, damit Sie sich nicht darauf verlassen können. –
- 1. C++ Stapel gemeinsamer Zeiger löschen Element
- 2. Warum ist das ein Zeiger
- 3. Warum ist dieser Zeiger auf Zeiger auf char aktuell?
- 4. Fehler mit Zeiger auf ein Array
- 5. Warum verwendet cudaMalloc() Zeiger auf Zeiger?
- 6. So löschen Sie Stapel als Stapel?
- 7. Setzen Zeiger auf NULL vor dem Löschen
- 8. Aufruf auf das gleiche Objekt auf zwei Zeiger löschen
- 9. Warum ist es nicht möglich, ein Byte auf einen Stapel auf Pentium IA-32 zu schieben?
- 10. Stapel im Visual Studio-Direktfenster löschen
- 11. C++, Stapel und Zeiger der Struktur
- 12. Was ist ein Verweis auf einen Zeiger?
- 13. Löschen des Objekts, das ein Zeiger in einem Zeigervektor auf
- 14. Löschen TCHAR Zeiger
- 15. C++ Löschen eines Zeigers auf einen Zeiger
- 16. Mips_how verwendet Mips Frame-Zeiger fp auf dem Stapel?
- 17. Wie erstelle ich einen int Zeiger auf dem Stapel?
- 18. temporäres Objekt als Argument auf dem Stapel
- 19. TypeError: "Stapel" ist schreibgeschützt
- 20. Zeiger auf ein Array
- 21. einen kopierten Zeiger löschen
- 22. -Update ein Zeiger auf einen void-Zeiger
- 23. Warum Umbruch ist für Warteschlange erforderlich, aber nicht für Stapel?
- 24. Der Stapel ist ein Implementierungsdetail oder nicht?
- 25. Was ist ein synthetischer Zeiger?
- 26. Nicht möglich: Dieser Zeiger ist ein Standardargument. Warum?
- 27. Hauptgründe, warum Programmiersprachen-Laufzeiten Stapel verwenden?
- 28. Ist es sicher, ein POD-Objekt durch einen Zeiger auf seine Basis zu löschen?
- 29. Warum fungiert ein C++ - Zeiger auf ein Zeichen als Zeichenfolge, obwohl kein Nullabschluss vorhanden ist?
- 30. warum keine implizite Konvertierung von Zeiger auf const Zeiger
müssen Sie wissen, was zuerst Stapel ist. Wenn Sie Speicher im Stack löschen, wird Ihr Stack nicht mehr zusammenhängend sein, aber die Laufzeit hängt von dieser Tatsache ab. – Incomputable
Anders ist nicht das Gleiche. - Fred Picker –
Sie löschen keinen Zeiger, den Sie nicht "neu" gemacht haben. Es gibt nichts tiefer als das, es ist nur was die Regeln der Sprache sind. – dxiv