[Gelöst] Eigene Exception / Kaputter e.what String

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

[Gelöst] Eigene Exception / Kaputter e.what String

Beitrag von BeRsErKeR »

Hallo ich hab mir meine eigene Exception-Klasse geschrieben, die natürlich von std::exception (genauer von std::runtime_error) erbt. Diese erhält einfach im Ctor ein paar mehr Angaben (einen String und einen Integer). Ich überlade nun die what-Methode, in der ich mit einem std::ostringstream die Nachricht und die beiden neuen Angaben "zusammen-streame" und dann folgenden Code ausführe:

Code: Alles auswählen

return MyStream.str().c_str();
Wenn ich mit dem Debugger durchgehe gibt sowohl str(), als auch c_str() das gewünschte Ergebnis zurück. Einen Step später steh ich dann wieder im catch-Block:

Code: Alles auswählen

catch (const std::exception &e)
{
    IrgendeineErrorFunktion(e.what());
}
Das Kuriose ist nun, dass hier e.what() nur noch Murks liefert. Um genau zu sein eine größere Anzahl von merkwürdigen Zeichen (immer die gleichen).

Nun vermute ich mal ganz stark dass zwischen dem Werfen und dem Fangen der Exception irgendwas kaputt geht, wobei das what() ja eigentlich erst im catch-Block aufgerufen wird. Aber da wird ja kein Code mehr danach ausgeführt, daher denk ich die Exception ist irgendwie ein wenig kaputt. Da ich allerdings nicht so in der Exception-Materie drin stecke und hier sicherlich einige mehr Ahnung haben, wollt ich mal in die Runde fragen, ob jemand eine Idee hat was das sein könnte. Genauer würde mich interessieren wo das ganze im Speicher liegt. Also beispielsweise ob es wahrscheinlicher ist, dass der Code vor dem Werfen der Exception gefährlich zu Leibe rücken könnte oder eher der Code nahe des Fangens und so Sachen.

Es ist nämlich recht schwer das ganze vernünftig zu debuggen. Ich sehe nicht wirklich was da im Hintergrund während des Werf-Fang-Spiels passiert und habe leider, wie schon erwähnt, zu wenig Hintergrundwissen.

Danke für Hinweise.



Hier noch einige Informationen:
  • Visual Studio 2008
  • Windows 7 Enterprise 32 Bit
  • this-Pointer im what()-Aufruf: 0x0031e70c (Member haben die gewünschten Werte, std::runtime_error::what()-Aufruf liefert gewünschten Wert)
  • Inhalt von e im catch-Block {_m_what=0x00000000 <Bad Ptr> _m_doFree=0 } const std::exception &
    (Verwirrt mich etwas)
  • Error-Funktion

    Code: Alles auswählen

    void Error(const std::string &error)
    {
    	::MessageBoxA(0, error.c_str(), "Error", MB_ICONERROR | MB_OK);
    }
  • Catch-Block

    Code: Alles auswählen

    catch (const std::exception &e)
    {
    	ct::os::Error(e.what()); // Obige Error-Funktion befindet sich im namespace ct::os
    }
  • Exception-Klasse

    Code: Alles auswählen

    class recipe_error : public std::runtime_error
    	{
    	public:
    		recipe_error(const std::string &file, size_t line, const std::string &error) throw()
    		: std::runtime_error(error), File(file), Line(line), UseLine(true)
    		{
    
    		}
    
    		recipe_error(const std::string &file, const std::string &error) throw()
    		: std::runtime_error(error), File(file), Line(0), UseLine(false)
    		{
    
    		}
    
    		virtual ~recipe_error() throw()
    		{
    
    		}
    
    		virtual const char* what(void) const throw()
    		{
    			std::ostringstream Error;
    			Error << File;
    			if (UseLine)
    				Error << " (" << Line << ")";
    			Error << ": " << std::runtime_error::what();
    			return Error.str().c_str();
    		}
    
    	private:
    		std::string File;
    		size_t Line;
    		bool UseLine;
    	};
Zuletzt geändert von BeRsErKeR am 16.12.2011, 10:02, insgesamt 1-mal geändert.
Ohne Input kein Output.
joggel

Re: Eigene Exception / Kaputter e.what String

Beitrag von joggel »

BeRsErKeR hat geschrieben: Ich überlade nun die what-Methode, in der ich mit einem std::ostringstream die Nachricht und die beiden neuen Angaben "zusammen-streame" und dann folgenden Code ausführe:

Code: Alles auswählen

return MyStream.str().c_str();
Wenn ich mit dem Debugger durchgehe gibt sowohl str(), als auch c_str() das gewünschte Ergebnis zurück. Einen Step später steh ich dann wieder im catch-Block:

Code: Alles auswählen

catch (const std::exception &e)
{
    IrgendeineErrorFunktion(e.what());
}
Ist das ein Schreibfehler, dass du die std::exception fängst, oder sollte da deine Exception-Klasse rein?
Benutzeravatar
dot
Establishment
Beiträge: 1736
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Eigene Exception / Kaputter e.what String

Beitrag von dot »

Ich vermute mal MyStream ist eine lokale Variable in what()? In dem Fall ist's sonnenklar: MyStream existiert nichtmehr sobald what() returned und damit ist auch dein .c_str() futsch. Speicher doch in der exception einfach nur nen string und bastel den schon in Konstruktor zusammen ;)
Alexander Kornrumpf
Moderator
Beiträge: 2131
Registriert: 25.02.2009, 13:37

Re: Eigene Exception / Kaputter e.what String

Beitrag von Alexander Kornrumpf »

dot hat geschrieben:Ich vermute mal MyStream ist eine lokale Variable in what()? In dem Fall ist's sonnenklar: MyStream existiert nichtmehr sobald what() returned und damit ist auch dein .c_str() futsch. Speicher doch in der exception einfach nur nen string und bastel den schon in Konstruktor zusammen ;)
Du musst nicht vermuten, Code ist dabei:

Code: Alles auswählen

virtual const char* what(void) const throw()
{
std::ostringstream Error;
Error << File;
if (UseLine)
Error << " (" << Line << ")";
Error << ": " << std::runtime_error::what();
return Error.str().c_str();
}
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Eigene Exception / Kaputter e.what String

Beitrag von BeRsErKeR »

dot hat geschrieben:Ich vermute mal MyStream ist eine lokale Variable in what()? In dem Fall ist's sonnenklar: MyStream existiert nichtmehr sobald what() returned und damit ist auch dein .c_str() futsch. Speicher doch in der exception einfach nur nen string und bastel den schon in Konstruktor zusammen ;)
Mist diese doofen char-Pointer. Exceptions sind halt so gut wie die einzigen Stellen wo ich noch char-Pointer nutze. Mit std::string-Kopien hat man sowas nicht, daher trat das auch das erste Mal auf. Manchmal sieht man halt den Wald vor Bäumen nicht ... Danke
Ohne Input kein Output.
Benutzeravatar
dot
Establishment
Beiträge: 1736
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Eigene Exception / Kaputter e.what String

Beitrag von dot »

Alexander Kornrumpf hat geschrieben:
dot hat geschrieben:Ich vermute mal MyStream ist eine lokale Variable in what()? In dem Fall ist's sonnenklar: MyStream existiert nichtmehr sobald what() returned und damit ist auch dein .c_str() futsch. Speicher doch in der exception einfach nur nen string und bastel den schon in Konstruktor zusammen ;)
Du musst nicht vermuten, Code ist dabei:
Ah, übersehn :mrgreen:
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Eigene Exception / Kaputter e.what String

Beitrag von BeRsErKeR »

dot hat geschrieben:
Alexander Kornrumpf hat geschrieben:
dot hat geschrieben:Ich vermute mal MyStream ist eine lokale Variable in what()? In dem Fall ist's sonnenklar: MyStream existiert nichtmehr sobald what() returned und damit ist auch dein .c_str() futsch. Speicher doch in der exception einfach nur nen string und bastel den schon in Konstruktor zusammen ;)
Du musst nicht vermuten, Code ist dabei:
Ah, übersehn :mrgreen:
Tztztz da macht man sich so viel Mühe möglichst viele Informationen weiterzugeben und dann wird's doch übersehen. :P
Ohne Input kein Output.
Benutzeravatar
dot
Establishment
Beiträge: 1736
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Gelöst] Eigene Exception / Kaputter e.what String

Beitrag von dot »

:P
Antworten