开发者

C++ -- Why 'what' print "Unknown exception" in catch scope?

开发者 https://www.devze.com 2023-03-27 10:03 出处:网络
try { range_error r(\"Hi I am hereeeee!\"); cout << r.what() << endl;// print \"Hi I am hereeeee!\"// case one
try
{
    range_error r("Hi I am hereeeee!");
    cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
    exception *p2 = &r; 
  开发者_开发知识库  cout << p2->what() << endl; // print "Hi I am hereeeee!"  // case two
    throw p2;
}
catch (exception *e)
{
    cout << e->what() << endl;  // print "Unknown exception"  // case three
}

Question>

I don't know why case three prints "Unknown exception" instead of "Hi I am hereeeee!"? The printed result is copied from VS2010


This program results in undefined behavior. Because the variable r is declared inside the try block, it goes out of scope before the catch handler is invoked. At this point, e points to some area on the stack where an object of type range_error used to exist.

The following program should print the expected results:

range_error r("Hi I am hereeeee!");
try
{
    cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
    exception *p2 = &r; 
    cout << p2->what() << endl; // print "Hi I am hereeeee!"  // case two
    throw p2;
}
catch (exception *e)
{
    cout << e->what() << endl;  // print "Hi I am hereeeee!"  // case three
}

However, you should not throw a pointer to an object, you should throw the object itself. The run-time library will store a copy of the range_error object and pass that copy to the exception handler.

Thus, you should use the following code instead:

try
{
    range_error r("Hi I am hereeeee!");
    cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
    throw r;
}
catch (const exception& e)
{
    cout << e.what() << endl;  // print "Hi I am hereeeee!"  // case two
}


Because by the time you get to the catch, your range_error has been destroyed and you're catching a dangling pointer. Either move the range_error declaration outside the try block or, better yet, throw an instance and catch by reference.


Because the pointed to exception object has gone out of scope by the time you catch the exception. If you wrote

range_error r("Hi I am hereeeee!");
try
{
    cout << r.what() << endl;   // print "Hi I am hereeeee!"  // case one
    exception *p2 = &r; 
    cout << p2->what() << endl; // print "Hi I am hereeeee!"  // case two
    throw p2;
}
catch (exception *e)
{
    cout << e->what() << endl;  // print "Unknown exception"  // case three
}

it would print what you expected.

0

精彩评论

暂无评论...
验证码 换一张
取 消