параметр исключения c ++ - PullRequest
3 голосов
/ 09 марта 2010

У меня есть вопрос относительно следующего фрагмента кода, с которым я столкнулся в одной из наших старых библиотек.

try
{
  throw "this is an error message";
}
catch( char* error )
{
  cout << "an exception occured: " << error << endl;
}

Мое понимание поведения в этом случае заключается в том, что сообщение об ошибке генерируется по значению, что означает копию текста

"это сообщение об ошибке"

брошен. Предложение catch указывает указатель на char как ожидаемый тип исключения. Может ли кто-нибудь просветить меня, почему это работает? Другой вопрос в этом контексте касается памяти, выделенной для сообщения об ошибке. Поскольку типом исключения является указатель на char *, можно предположить, что память для сообщения об ошибке была выделена динамически в куче и должна быть удалена пользователем?

Заранее спасибо

Ответы [ 6 ]

9 голосов
/ 09 марта 2010

В throw контекстные массивы распадаются на указатели. А строковый литерал - это массив символов. Это означает, что:

(1) В данном случае «выбрасывается по значению» указатель const char * на существующий строковый литерал. Копия строкового литерала не производится. Никакой дополнительной памяти не выделяется этим throw. Там нет необходимости освобождать что-либо.

(2) Чтобы поймать это исключение, вам нужен обработчик catch (const char *). Ваш обработчик char * не поймает его, если только в вашем компиляторе нет ошибки (это известная постоянная ошибка в компиляторах MSVC ++, которая даже не исправлена ​​опцией /Za).

5 голосов
/ 09 марта 2010

На самом деле он должен перехватить const char*, потому что это тип строковых констант как в C, так и в C ++.

Передается по значению, но по значению указателя.

Его не следует удалять, поскольку, как ясно видно из кода, динамическое размещение отсутствует.

2 голосов
/ 09 марта 2010

Это не строка, которая генерируется, а указатель на строку. Вы не должны удалять это. Указатель указывает на строковый литерал, созданный в точке вызова:

throw "this is an error message";

Эта строка размещается не в стеке, а статически. Вы можете думать об этом как о постоянной времени компиляции.

0 голосов
/ 09 марта 2010

Мое понимание поведения в этом случае заключается в том, что сообщение об ошибке генерируется по значению, что означает, что копия текста [...] выбрасывается.

Нет, это означает, что копия указателя брошена.

0 голосов
/ 09 марта 2010

Я думаю, что вы почти правы, и сообщение отбрасывается по значению. Но не символом [XXX]. Это брошено символом *. И данные хранятся в статической памяти.

0 голосов
/ 09 марта 2010

Это работает, потому что типом «ANY STRING» по умолчанию является указатель на статический массив символов.

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