progfan
progfan

Reputation: 2526

C++ custom exception message not displaying

I am trying to create a custom exception class, throw it, and display the error message, but I am doing something wrong, causing the exception to not get thrown and the message to not get printed.

Here's the exception class:

class UnbalancedParenthesesException : public std::exception {
  int line_number {0};
public:
  UnbalancedParenthesesException(int line_number) :
    line_number { line_number }
    {}

  virtual const char* what() const throw() {
    std::string exception_message =
      "Papentheses imbalance at line " + std::to_string(line_number) + "\n";

    return exception_message.c_str();
  }
};

I am trying totry/throw/catch as follows:

void handle_closed_paren(int line_number) {
  try { 
    if (definitely_unbalanced()) {
      throw UnbalancedParenthesesException(line_number);
    }
  } catch (const UnbalancedParenthesesException& e) {
      std::out << e.what() << "\n";
}

There is nothing pertinent to this error in the console.

Thanks in advance.

Upvotes: 1

Views: 2258

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 595971

Your what() method is creating a local std::string variable and then returning a pointer to its internal data, which will be left dangling when the std::string goes out of scope and is destroyed when what() exits.

You need to store your error message in a std::string that is a member of the class so it does not go out of scope prematurely. Fortunately, std::exception already has an internal std::string for that purpose. So, instead of formatting the error message in what() itself, you should format it in your derived constructor and pass it to the base class constructor, letting the base what() method return it as-is:

class UnbalancedParenthesesException : public std::exception
{
    int mLineNumber;
public:
    UnbalancedParenthesesException(int line_number) : std::exception("Parentheses imbalance at line " + std::to_string(line_number)), mLineNumber(line_number) {}

    // optional, if the catcher needs access to the value
    int lineNumber() const { return mLineNumber; }
};

Upvotes: 3

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

Your program has undefined behaviour as you are returning the result of c_str() on a std::string that goes out of scope. Anything could happen.

Beyond that, if you're not seeing an exception then one was not thrown, probably because the result of definitely_unbalanced() is falsey.

Step through your program using your debugger.

Upvotes: 2

Related Questions