简体   繁体   中英

C++ I don't understand my exceptions what() behavior

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM