Попробуйте / поймайте ошибку сегментации в Linux - PullRequest
10 голосов
/ 05 февраля 2009

У меня есть приложение на Linux C ++, и я хотел бы проверить правильность указателя объекта перед разыменованием его. Однако try / catch не работает для этого в Linux из-за ошибки сегментации. Как это можно сделать?

Ответы [ 9 ]

8 голосов
/ 05 февраля 2009

Если у вас есть сценарий, в котором многие указатели в вашем приложении ссылаются на одни и те же объекты с ограниченным сроком службы, популярным решением является использование повышения интеллектуальных указателей . Редактировать: в C ++ 11 оба эти типа доступны в стандартной библиотеке

Вы хотели бы использовать shared_ptr для указателей, которые отвечают за время жизни вашего объекта, и weak_ptr для других указателей, которые могут стать недействительными , Вы увидите, что weak_ptr имеет встроенную проверку достоверности, которую вы запрашиваете.

8 голосов
/ 05 февраля 2009

Ошибка сегментации не является исключением (как в Java NullPointerException); это сигнал от ОС к процессу. Взгляните на справочную страницу для sigaction , чтобы узнать, как установить обработчик для ошибки сегментации (SIGSEGV).

4 голосов
/ 05 февраля 2009

Вы можете включить обработчик сигнала для SIGSEGV для этого одного случая. См. Справочную страницу "сигнал" для деталей. Другой альтернативой является использование ссылок, которые гарантированно действительны. Конечно, это зависит от вашей заявки.

4 голосов
/ 05 февраля 2009

Инициализируйте ваш указатель на NULL. Если после некоторой обработки он все еще равен NULL, он недействителен, в противном случае он действителен.

2 голосов
/ 05 февраля 2009

Не существует естественного, универсального способа с необработанными указателями C ++. C ++ предполагает, что вы будете отслеживать эту информацию.

В большинстве случаев вы можете справиться с этим, не забывая устанавливать указатели в NULL, когда они недействительны. Новые указатели, которые изначально не указывают, должны быть установлены в NULL, а недавно удаленные объекты должны иметь свои указатели в NULL.

1 голос
/ 05 февраля 2009

Как вы проверяете указатель на достоверность? Сравнить с NULL?

Лучшее, что вы делаете, это запускаете программу под Valgrind . Ошибка может быть в другом месте.

Обновление: на платформе Win32 есть что-то вроде __try __except, которое позволяет отлавливать некоторые исключения. Насколько я знаю, для этой функции Win32 нет эквивалента в Linux.

0 голосов
/ 25 февраля 2009

Как правило, относительно довольно странной идеи «проверки ненулевого указателя на достоверность», взгляните на эту статью: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx («IsBadXxxPtr действительно должен называться CrashProgramRandomly»)

0 голосов
/ 05 февраля 2009

Указатели хранятся в объектах. Они инициализируются в конструкторе, потенциально равным 0 (NULL). Они удаляются в деструкторе, возможно, в назначении и редко в других функциях. При удалении из членов, отличных от деструктора, им сразу же присваивается новое значение или 0.

0 голосов
/ 05 февраля 2009

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

Помимо проверки на NULL, я не верю, что есть способ проверить, является ли указатель «действительным» в том смысле, который вы описываете. Во время нормальной работы подобные ошибки не должны возникать, поскольку они представляют собой ошибку, поэтому вы должны захотеть, чтобы ваша программа не работала, хотя и изящно.

...