Мне нужно знать причину ошибки сегментации (SIGSEGV) и как ее устранить.
Что вызывает SIGSEGV
Ответ 1
Wikipedia имеет ответ, а также ряд других источников.
Segfault в основном означает, что вы сделали что-то плохое с указателями. Это, вероятно, segfault:
char *c = NULL;
...
*c; // dereferencing a NULL pointer
Или это:
char *c = "Hello";
...
c[10] = 'z'; // out of bounds, or in this case, writing into read-only memory
Или, может быть, это:
char *c = new char[10];
...
delete [] c;
...
c[2] = 'z'; // accessing freed memory
Один и тот же основной принцип в каждом случае - вы делаете что-то с памятью, которая не принадлежит вам.
Ответ 2
Существуют различные причины сбоев сегментации, но в основном вы неправильно обращаетесь к памяти. Это может быть вызвано разыменованием нулевого указателя или попыткой изменить память в режиме readonly или с помощью указателя на то место, которое не отображается в пространство памяти вашего процесса (это, вероятно, означает, что вы пытаетесь использовать число в качестве указателя, или вы увеличили указатель слишком далеко). На некоторых машинах возможен неправильный доступ через указатель, чтобы вызвать проблему - если у вас есть нечетный адрес и, например, попытается прочитать четное количество байтов, например (которое может генерировать SIGBUS, вместо этого).
Ответ 3
с использованием указателя invalid/null? Переопределение границ массива? Kindof трудно быть конкретным без какого-либо образца кода.
По сути, вы пытаетесь получить доступ к памяти, которая не принадлежит вашей программе, поэтому ОС ее убивает.
Ответ 4
Вот пример SIGSEGV.
[email protected]:/opt/playGround# cat test.c
int main()
{
int * p ;
* p = 0x1234;
return 0 ;
}
[email protected]:/opt/playGround# g++ -o test test.c
[email protected]:/opt/playGround# ./test
Segmentation fault
И вот detail.
Как это сделать?
-
Избегайте его как можно больше в первое место.
Защитите программу: используйте assert(), проверьте указатель NULL, проверьте переполнение буфера.
Используйте инструменты статического анализа, чтобы изучить ваш код.
скомпилируйте свой код с помощью -Werror -Wall.
Кто-нибудь просматривает ваш код.
-
Когда это действительно произошло.
Осмотрите внимательно код.
Проверьте, что вы изменили с момента последнего успешного выполнения кода без сбоя.
Надеюсь, gdb предоставит вам стек вызовов, чтобы вы знали, где произошел сбой.
ИЗМЕНИТЬ: извините за спешку. Он должен быть *p = 0x1234;
вместо p = 0x1234
;
Ответ 5
Ошибка сегментации возникает, когда вы обращаетесь к памяти, которая не объявлена программой. Вы можете сделать это через указатели, то есть через адреса памяти. Или это также может быть связано с переполнением стека, например:
void rec_func() {int q = 5; rec_func();}
int main() {rec_func();}
Этот вызов будет продолжать использовать стековую память до тех пор, пока она не будет полностью заполнена и, таким образом, в итоге не произойдет стекопоток. Примечание: он может быть не виден в некоторых конкурентных вопросах, так как он сначала приводит к timeouterror, но для тех, в которых тайм-аут не происходит, трудно понять sigsemv.
Ответ 6
SigSegV означает сигнал о нарушении доступа к памяти, попытке чтения или записи из/в область памяти, к которой у вашего процесса нет доступа. Это не исключения C или C++, и вы не можете поймать сигналы. Действительно, можно написать обработчик сигнала, который игнорирует проблему и позволяет продолжить выполнение вашей нестабильной программы в неопределенном состоянии, но должно быть очевидно, что это очень плохая идея.
В большинстве случаев это происходит из-за ошибки в программе. Указанный адрес памяти может помочь отладить причину проблемы (если он близок к нулю, то, скорее всего, разыменование нулевого указателя, если адрес что-то вроде 0xadcedfe, то его преднамеренная защита или проверка отладки и т.д.)
Один из способов "поймать" сигнал - запустить ваш материал в отдельном дочернем процессе, который затем может внезапно завершиться, не прерывая при этом ваш основной процесс. Поиск основной причины и ее устранение, очевидно, предпочтительнее, чем подобные обходные пути.