Why does this code work only when I use a char[] from the stack

Started by
2 comments, last by Washu 18 years, 4 months ago
I have the following structure used for exception handling:
struct EWinApi : public std::runtime_error {
	EWinApi() : runtime_error(_("Windows API error")) {}
	EWinApi(const std::string& msg) : runtime_error(msg) {}
	virtual const char *what() const throw() {
		char msg[512];
		wxString wxmsg;
		wxmsg.Printf("%s (%x: %s)", std::runtime_error::what(),
			wxSysErrorCode(), wxSysErrorMsg());
		strcpy(&msg[0], wxmsg.c_str());
		return &msg[0];
	}
};
I have to use `strcpy` for this to use. If I just do `return wxmsg.c_str();` I get : The string is accessed with catch(e) { msg(e.what()); } Is there a better way to do this? Or am I doing it right? I just realized I can just use sprintf... but I typed all this up so let's see...
Advertisement
What you have there only works by accident. The reason you needed the strcpy is that, as soon as you return, the wxString goes out of scope, thereby invalidating the .c_str(). Since msg is also being allocated on the stack, you should not be returning it's address either. If you make msg (or wxmsg depending on which one you want to return) a member of the class/struct, you could then safely do what you are doing.
When you do 'return wxmsg.c_str()' you are returning a pointer to an object on the stack (wxmsg) that gets destroyed when your function returns.

When you strcpy to the char buffer you are basically tweaking things but it will still break depending on the context what() is called from.

Basically go back to CS101 where they should have drilled it into you never to return pointers to local variables. That's what you're doing in both versions.

I've never really used custom exceptions so I don't know what the standard pattern is for this sort of thing. Building the entire error string in the constructor comes to mind.
-Mike
That exception is really bad. First of all, you are returning the address of a temporary, which is undefined. Secondly, the error code and message could have easily changed between the time of the exceptions construction, and the time of what() being called.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

This topic is closed to new replies.

Advertisement