Ошибка сегментацииОшибка сегментации (англ. Segmentation fault, сокр. segfault, жарг. сегфолт) — ошибка программного обеспечения, возникающая при попытке обращения к недоступным для записи участкам памяти либо при попытке изменить память запрещённым способом. В системах на основе процессоров Motorola 6800 эти ошибки, как правило, известны как ошибки адреса или шины. В UNIX-подобных операционных системах процесс, обращающийся к недействительным участкам памяти, получает сигнал SIGSEGV. В Microsoft Windows процесс, получающий доступ к недействительным участкам памяти, создаёт исключение STATUS_ACCESS_VIOLATION (определение для кода 0xC0000005[1]) и, как правило, предлагает запустить отладчик приложения и показывает пользователю окно с предложением отправить отчёт об ошибке в Microsoft. ПримерВот пример кода ANSI C, который приводит к ошибке сегментации из-за присутствия квалификатора типа const char * s = "hello world";
* (char *) s = 'H';
Когда программа, содержащая этот код, скомпилирована, строка Компиляция и запуск таких программ на OpenBSD 4.0 вызывает следующую ошибку выполнения: $ gcc segfault.c -g -o segfault
$ ./segfault
Segmentation fault
Program received signal SIGSEGV, Segmentation fault.
0x1c0005c2 in main () at segfault.c:6
6 *s = 'H';
В отличие от этого, GCC 4.1.1 на GNU/Linux возвращает ошибку ещё во время компиляции: $ gcc segfault.c -g -o segfault
segfault.c: In function 'main':
segfault.c:4: error: assignment of read-only location
Условия, при которых происходят нарушения сегментации, и способы их проявления зависят от операционной системы. Этот пример кода создаёт нулевой указатель и пытается присвоить значение по несуществующему адресу. Это вызывает ошибки сегментации во время выполнения программы на многих системах. int * ptr = (int *) 0;
*ptr = 1;
Ещё один способ вызвать ошибку сегментации заключается в том, чтобы вызвать функцию int main()
{
main();
}
Обычно ошибка сегментации происходит потому, что:
Например, char * p1 = NULL; /* инициализирован как нулевой; это допускается, но на многих системах он не может быть разыменован */
char * p2; /* вообще не инициализирован (указывает на произвольный адрес в памяти) */
char * p3 = (char *) malloc(20); /* хорошо, участок памяти выделен */
free(p3); /* но теперь его больше нет */
Теперь разыменование любого из этих указателей может вызвать ошибку сегментации. Или при использовании массивов, если случайно указать в качестве размера массива неинициализированную переменную: int main()
{
const int nmax = 10;
int i, n, a[n];
}
Компилятор G++ не прослеживает такую ошибку при компоновке, что при запуске скомпилированной программы может вызвать ошибку сегментации. См. такжеПримечания
Ссылки
|