Search code examples
c++arraysstringexceptionstdstring

C++ Weird string/char* exception behaviour


Well here is my exception code :

class OptionNotFoundError: public std::exception {
public:
    OptionNotFoundError(std::string option, int position) throw()
        : option(option), position(position) {}
    OptionNotFoundError(char option_, int position) throw()
        : position(position) { option.push_back(option_); }

    virtual ~OptionNotFoundError() throw() {}

    virtual const char* what() const throw() {
        std::string what_str = "Option '" + option + "' not found in position " + std::to_string(position);
        std::cout << what_str.c_str() << std::endl;
        return what_str.c_str();;
    }

    std::string option;
    int position;
};

When the exception is thrown, here is what I get in the terminal :

terminate called after throwing an instance of 'Args::OptionNotFoundError'
Option 'c' not found in position 1
  what():  

So the cout works fine, but… not the return. If I use return "smth" it works fine.

Weirder : if I replace what_str definition with

std::string what_str = "test";

I get

terminate called after throwing an instance of 'Args::OptionNotFoundError'
test
  what():  x�zL�

Again, the cout<< works fine. But the return… Not so much. Is this some encoding error ?


Solution

  • For the 1st case, note that what_str is a local variable inside what(), it'll be destroyed when get out of the function scope, then the pointer returned by it becomes dangled, dereference on it leads to UB.

    For the 2nd case, returning "smth" works fine, because "smth" is a const char[5], which is a string literal,

    String literals have static storage duration, and thus exist in memory for the life of the program.

    For the 3rd case,

    if i replace what_str definition with

    std::string what_str = "test";
    

    It doesn't work, because what_str is still a local std::string, the problem is same with the 1st case.