Ich verstehe, dass wenn etwas throw
n ist, der Stapel bis zu dem Punkt 'abgewickelt' wird, an dem es abgefangen wird, und die Destruktoren von Klasseninstanzen auf dem Stapel in jedem Funktionskontext ausgeführt werden (weshalb Sie keine Ausnahme von einem Destruktor auslösen sollten - Sie könnten am Ende einen zweiten werfen) ... aber ich frage mich, wo im Speicher das Objekt gespeichert ist, das ich geworfen habe, während dies geschieht?
Ist es implementierungsabhängig? Wenn ja, gibt es eine bestimmte Methode, die von den meisten gängigen Compilern verwendet wird?
c++
exception
exception-handling
sje397
quelle
quelle
raise
zerstören Sie es, sobald Sie mit dem Abwickeln fertig sind (einschließlich der Möglichkeit, Fangklauseln die Möglichkeit zu geben, die Ausnahme durch Bezugnahme zu behandeln und sie erneut zu behandeln). Das Problem bei der Heap-Zuweisung ist, was tun Sie, wenn Ihr Versuch, die Ausnahme zuzuweisen, fehlschlägt? Sie müssten abbrechen (genau wie beim Stapelüberlauf, wenn das Ablegen auf dem Stapel aufgrund von Platzmangel "fehlschlägt"). Im Gegensatz zu Java darf die Implementierung stattdessen keine andere Ausnahme auslösen.Antworten:
Ja, die Antwort ist vom Compiler abhängig.
Ein kurzes Experiment mit meinem Compiler (
g++ 4.4.3
) zeigt, dass seine Laufzeitbibliothek zuerst versucht,malloc
Speicher für die Ausnahme zu erstellen, und andernfalls versucht, Speicherplatz in einem prozessweiten "Notfallpuffer" zuzuweisen, der sich im Datensegment befindet. Wenn das nicht klappt, ruft es anstd::terminate()
.Es scheint, dass der Hauptzweck des Notfallpuffers darin besteht, werfen zu können,
std::bad_alloc
nachdem der Prozess keinen Heap-Speicherplatz mehr hat (in diesem Fall würde dermalloc
Aufruf fehlschlagen).Die relevante Funktion ist
__cxa_allocate_exception
:Ich weiß nicht, wie typisch dieses Schema ist.
quelle
malloc
Anruf fehlschlagen", normalerweise, aber nicht unbedingt.Von dieser Seite :
Dies ist nur der Itanium ABI und ich suche nach Details, die für GCC, Clang und MSVC spezifisch sind. Der Standard spezifiziert jedoch nichts und dies scheint der offensichtliche Weg zu sein, um Ausnahmespeicher zu implementieren, also ...
quelle
Ich weiß nicht, ob dies Ihre Frage beantworten wird, aber dies (wie ein C ++ - Compiler die Ausnahmebehandlung implementiert) ist ein ausgezeichneter Artikel über die Ausnahmebehandlung überhaupt :. Ich empfehle es sehr (:
Entschuldigen Sie die kurze Antwort, aber die gesamten Informationen im Artikel sind großartig. Ich kann hier keine Informationen auswählen und veröffentlichen.
quelle
excpt_info
dieser Seite nach Informationen darüber, wie MSVC dies tut.Der C ++ - Standard gibt im Allgemeinen an, wie sich die Sprache verhält, nicht jedoch, wie der Compiler dieses Verhalten implementieren soll. Ich denke, diese Frage fällt in diese Kategorie. Der beste Weg, so etwas zu implementieren, hängt von den Besonderheiten der Maschine ab - einige Prozessoren haben viele Allzweckregister, andere nur sehr wenige. Ein Prozessor kann sogar nur für Ausnahmen mit einem speziellen Register erstellt werden. In diesem Fall sollte der Compiler die Möglichkeit haben, diese Funktion zu nutzen.
quelle
Nun, es kann nicht auf dem Stapel sein, da das abgewickelt wird, und es kann nicht auf dem Haufen sein, da dies bedeuten würde, dass das System wahrscheinlich nicht werfen könnte
std::bad_alloc
. Davon abgesehen liegt es ganz bei der Implementierung: Nicht die Implementierung angegeben (die dokumentiert werden muss), sondern nicht angegeben. (Eine Implementierung kann den Heap die meiste Zeit verwenden, solange sie über eine Art Notfallsicherung verfügt, die eine begrenzte Anzahl von Ausnahmen zulässt, selbst wenn kein Speicher mehr vorhanden ist.)quelle
std::bad_alloc
funktionieren. Dies bedeutet, dass eine Implementierung den Heap nicht systematisch verwenden kann. Der Standard erlaubt es nicht. Ich stütze meine Ansprüche auf den Standard.