views:

217

answers:

2

How do I catch wrong array reference in C++? Why doesn't the following code work:

    #include <exception>

    int * problemNum = new int;
    int (* p [100])() = {problem1, problem2, problem3};

    ...

    try {
        cout << (*p[*problemNum-1])();
    }
    catch (exception){
        cout << "No such problem";
    }

My compiler says: Unhandled exception at 0xcccccccc in Euler.exe: 0xC0000005: Access violation. when I initiate bad reference by inputting 0 as *problemNum.

+3  A: 

Becauce C++ can't handle such errors with its exception mechanism. See Defective C++ on that issue.

Use sigaction(2).

sigaction - examine and change a signal action

SYNOPSIS

   #include <signal.h>

   int sigaction(int signum, const struct sigaction *act,
                 struct sigaction *oldact);

DESCRIPTION The sigaction() system call is used to change the action taken by a process on receipt of a specific signal. signum specifies the signal and can be any valid signal except SIGKILL and SIGSTOP. If act is non-null, the new action for signal signum is installed from act. If oldact is non-null, the previous action is saved in oldact. The sigaction structure is defined as something like:

       struct sigaction {
           void     (*sa_handler)(int);
           void     (*sa_sigaction)(int, siginfo_t *, void *);
           sigset_t   sa_mask;
           int        sa_flags;
           void     (*sa_restorer)(void);
       };

You need to catch SIGSEGV, you can attach your own handler (function which gets called when illegal memory access is performed).

alamar
You really don't want to start catching SIGSEGV in this case. It's absolutely wrong to use segmentation faults as an array boundary check. Better just use std::vector.
sth
+4  A: 

alamar is right - C++ won't catch exceptions with this type of array.

Use an STL vector instead:

#include <exception>
#include <vector>

int * problemNum = new int;
std::vector<int(*)()> p;
p.push_back(problem1);
p.push_back(problem2);
p.push_back(problem3);

...

try {
    cout << p.at(*problemNum-1)();
}
catch (exception){
    cout << "No such problem";
}
Adam Pierce
That won't trigger an exception, either. If you need an exception when accessing an out-of-bounds element, use the "at" member function, not the bracket operator.
Rob Kennedy
Dang you're right Rob, I never knew that! I'll change the code example.
Adam Pierce