Как понять вывод? - PullRequest
       13

Как понять вывод?

3 голосов
/ 11 ноября 2010
int main(int argc, char** argv)
{
    try {
            char *p2 = NULL;
            cout << "p2:" << strlen(p2) <<endl; 
                    cout << "mark";
        }
        catch (...) {
            cout << "caught exception" <<endl;
        }
    return 0;
}

Вывод p2:, поэтому ни cout << "mark";, ни cout << "caught exception" <<endl; не запустились, почему?

Ответы [ 5 ]

6 голосов
/ 11 ноября 2010

В C ++ разыменование NULL-указателя приводит к неопределенному поведению , что означает, что может произойти все: компьютер может взорваться, функция может вернуть произвольное значение, программа может быть уничтожена из-за исключения операционной системы. (который, в отличие от выражения C ++, не может быть пойман с помощью try-catch).

Короче говоря, не делай этого .

Если вам действительно нужно сделать это по очень веской причине (например, обойти ошибку в библиотеке, над которой у вас нет абсолютно никакого контроля), посмотрите в вашей операционной системе поддержку таких вещей (например, SEH * 1011). * в Windows).

5 голосов
/ 11 ноября 2010

В POSIX -совместимых системах ваша программа получает сигнал SIGSEGV и умирает, как только вы звоните strlen(p2), поскольку p2 равно NULL.

Насколько мне известно, нет способа портативно перехватить segfaults с использованием исключений C ++.

3 голосов
/ 11 ноября 2010

Ваш код имеет неопределенное поведение. Следовательно, любой вывод или no вывод оба являются действительными результатами. Я предполагаю, что strlen вызывает нарушение прав доступа (по крайней мере, на x86), и ваша программа закрывается.

C ++ не генерирует исключения при попытке разыменовать нулевой указатель.

2 голосов
/ 11 ноября 2010

strlen() не генерирует исключения, потому что это функция C и C не имеет исключений. Это просто сбой вашей программы, когда вы даете ей плохой ввод. (Хотя это не обязательно.)

0 голосов
/ 11 ноября 2010

strlen (NULL) пытается разыменовать NULL-указатель. Это вызывает аппаратное исключение, которое не может быть перехвачено механизмом try-catch. Программа взрывается. У вас будет такой же сценарий, если вы попытаетесь выполнить деление на ноль.

По этой причине всегда полезно проверять, имеют ли указатели (не) значение NULL. Если указатель равен NULL где-то там, где его не должно быть (и вы рассматриваете это как исключительную ситуацию), вы можете вызвать программную исключение из этого места. Тело вашего блока catch было бы выполнено, если бы вы написали что-то вроде этого (до вызова strlen):

if(p2 == NULL)
    throw 1;

Вы забыли добавить endl-манипулятор в строку с надписью "mark". Должно быть:

cout << "mark" << endl;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...