Интернет магазин китайских планшетных компьютеров



Компьютеры - Ошибка сегментации - Пример

23 января 2011


Оглавление:
1. Ошибка сегментации
2. Пример



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

 char *s = "hello world";
 *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 на Linux возвращает ошибку ещё во время компиляции:

$ gcc segfault.c -g -o segfault
segfault.c: In function ‘main’:
segfault.c:4: error: assignment of read-only location

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

Этот пример кода создаёт нулевой указатель и пытается присвоить значение по несуществующему адресу. Это вызывает ошибки сегментации во время выполнения программы на многих системах.

 int* ptr = 0;
 *ptr = 1;

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

 int main
 {
     main;
 }

Обычно, ошибка сегментации происходит потому что: указатель или нулевой, или указывает на произвольный участок памяти, или указывает на удаленный участок памяти.

Например,

    char* p1 = NULL;  /* инициализирован как нулевой, в чем нет ничего плохого, но на многих системах он не может быть разыменован */
    char* p2;  /* вообще не инициализирован */
    char* p3  = malloc;  /* хорошо, участок памяти выделен */
    free;  /* но теперь его больше нет */

Теперь разыменование любого из этих указателей вызовет ошибку сегментации.

Также, при использовании массивов, если случайно указать вместо максимального размера массива его текущий. Вот пример :

int main
{ int const nmax=10;
  int i,n,a;
}

такая ошибка не прослеживается g++ при линковке, но при ./a.out вызовет ошибку сегментации



Просмотров: 2057


<<< Плоская модель памяти