WikiSort.ru - Программирование

ПОИСК ПО САЙТУ | о проекте

Ошибка сегментации (англ. Segmentation fault, сокр. segfault, жарг. сегфолт) — ошибка программного обеспечения, возникающая при попытке обращения к недоступным для записи участкам памяти либо при попытке изменить память запрещённым способом. В системах на основе процессоров Motorola 68000 эти ошибки, как правило, известны как ошибки адреса или шины.

Сегментная адресация памяти является одним из подходов к управлению и защите памяти в операционной системе. Для большинства целей она была вытеснена страничной памятью[источник не указан 2861 день], однако, в документациях по традиции используют термин «Ошибка сегментации». Некоторые операционные системы до сих пор используют сегментацию на некоторых логических уровнях, а страничная память используется в качестве основной политики управления памятью.

В UNIX-подобных операционных системах процесс, обращающийся к недействительным участкам памяти, получает сигнал SIGSEGV. В Microsoft Windows процесс, получающий доступ к недействительным участкам памяти, создаёт исключение STATUS_ACCESS_VIOLATION и, как правило, предлагает запустить отладчик приложения и показывает пользователю окно с предложением отправить отчёт об ошибке в Microsoft.

Пример

Вот пример кода ANSI C, который приводит к ошибке сегментации из-за присутствия квалификатора типа const:

const char * s = "hello world";
* (char *) s = 'H';

Когда программа, содержащая этот код, скомпилирована, строка "hello world" размещена в секции программы с бинарной пометкой «только для чтения». При запуске операционная система помещает её с другими строками и константами в сегмент памяти, предназначенный только для чтения. После запуска переменная s указывает на адрес начала строки, а попытка присвоить значение символьной константы 'H' через переменную в памяти приводит к ошибке сегментации.

Компиляция и запуск таких программ на OpenBSD 4.0 вызывает следующую ошибку выполнения:

$ gcc segfault.c -g -o segfault
$ ./segfault
Segmentation fault

Вывод отладчика gdb:

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;

Ещё один способ вызвать ошибку сегментации заключается в том, чтобы вызвать функцию main() рекурсивно, что приведёт к переполнению стека:

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++ не прослеживает такую ошибку при компоновке, что при запуске скомпилированной программы может вызвать ошибку сегментации.

См. также

Ссылки

Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии