dtgee
dtgee

Reputation: 1272

How to handle exception so my program still runs?

I'm writing a generic linked list class, and I'm overloading the * operator in my reverse iterator class. Here's what I have:

try
{
    return this->item->data;
}
catch (...)
{
    cout << "OUT OF RANGEEEEE" << endl;
}   

item, which is the node of my linked list class, might possibly be nullptr because my pointer is pointing to the rend() position. In that case, how could I handle that exception so that my program still runs? I tried running with this code, but my program crashes.

Also, would it be fine to just do something like this instead?

if (item == nullptr)
{
    throw std::out_of_range("Error message here!");
}
else
{
    return this->item->data;
}

EDIT: So I take it that my second implementation is better? But still, when I run my program with the second implementation, I can't continue my program. How can I get it to be safer and so my program will continue to run?

Upvotes: 1

Views: 183

Answers (2)

Michael Kristofik
Michael Kristofik

Reputation: 35188

Your program is still running once you're inside the catch block1. In order to continue, you'll have to return something other than this->item->data. What you return depends on what makes sense for the function that's calling you.

IMHO, this is a bad use-case for an exception. Hitting the end of a linked list is not exceptional, it's normal and expected. Presumably you want to throw an exception so you don't have to special-case return this->item->data for when you hit the end of the list. But in order to continue, you have to return something and then your caller has to check for it. You're just moving that work to another place and paying the cost of an exception in the process. A better solution is to check for null where it makes the most sense and be done. No exceptions, no extra cost.


  1. catch (...) is way too broad for this case. That catches everything. You should really try to limit it to std::out_of_range or one of its ancestors. Otherwise you get things you weren't expecting lumped into your catch block, and you likely won't be prepared to handle them.

Upvotes: 3

Benjamin Lindley
Benjamin Lindley

Reputation: 103713

Dereferencing a null pointer is undefined behavior. It never has been specified (by the standard) to throw an exception. That's why your first example crashes.

Your second example is good, if that's the behavior you want. The standard library behavior is to just leave invalid dereferences as they are (undefined). But if you want to implement a safer alternative, you're free to do so.

How can I get it to be safer and so my program will continue to run?

You can use try-catch blocks at whatever level you want. For example:

try {
    MyListType<int> my_list;
    // do a bunch of stuff here involving my_list::iterators
    // If one is improperly dereferenced, an `std::out_of_range`
    // exception will be thrown, and caught below
} catch (std::out_of_range & e) {
    // your error handling
}

I recommend you make your own specific type of exception though, possibly deriving from std::out_of_range. That way you're not catching exceptions from other libraries that you may not be prepared to handle.

Upvotes: 2

Related Questions