I'm writing a exception class with a what() method.
const char* what() const throw() {
return "test";
}
works fine, but
const char* what() const throw() {
return (std::string("test")).c_str();
}
seems to return a random result. Why?
std::string("test")
creates a temporary string object. c_str
returns a pointer to some internal storage of that temporary object. After the function exits, that's a dangling pointer – it points to invalid memory.
There is no way to circumvent this. You either have to make your string object more long-lived by declaring (and initialising, since the function is const
) it outside the function – or you need to manually allocate heap storage inside the function, copy the string there, and return a pointer to that storage. However, this is complicated, error-prone, and violates the contract of the function, because the user of your error class doesn't expect to free memory.
In fact, here's a simple implementation of an error class (toy, since I don't know your use-case) with this in mind:
struct my_logic_error : std::logic_error {
// `std::logic_error` already overrides `what`, we only need to initialise it!
my_logic_error(int errcode) :
std::logic_error{std::string{"Logic error occurred with error code "} +
std::to_string(errcode)} {}
};
Assuming you derive from an exception class without this luxury, your code gets minimally more complex:
struct my_error : std::exception {
my_error(int errcode) :
message{std::string{"Logic error occurred with error code "} +
std::to_string(errcode)} {}
char const* what() const noexcept {
return message.c_str();
}
private:
std::string message;
};
You store the string value in a member of your exception class, and you return c_str() on this member.
Doing a strdup can work, but the caller must free the memory, that's not a safe way of doing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.