Ошибка сегментации

Поделись знанием:
Перейти к: навигация, поиск

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

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

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



Пример

Вот пример кода ANSI C, который приводит к ошибке сегментации вследствие присутствия квалификатора типа [en.wikipedia.org/wiki/Type_qualifier] const [en.wikipedia.org/wiki/Const_%28computer_programming%29]:

 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()
 { 
     int const nmax=10;
     int i,n,a[n];
 }


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

См. также

Напишите отзыв о статье "Ошибка сегментации"

Ссылки

  • www.faqs.org/qa/qa-673.html  (англ.)
  • c-faq.com/null/null1.html  (англ.)
  • c-faq.com/null/varieties.html  (англ.)

Отрывок, характеризующий Ошибка сегментации

Через неделю вышел отпуск. Гусары товарищи не только по полку, но и по бригаде, дали обед Ростову, стоивший с головы по 15 руб. подписки, – играли две музыки, пели два хора песенников; Ростов плясал трепака с майором Басовым; пьяные офицеры качали, обнимали и уронили Ростова; солдаты третьего эскадрона еще раз качали его, и кричали ура! Потом Ростова положили в сани и проводили до первой станции.
До половины дороги, как это всегда бывает, от Кременчуга до Киева, все мысли Ростова были еще назади – в эскадроне; но перевалившись за половину, он уже начал забывать тройку саврасых, своего вахмистра Дожойвейку, и беспокойно начал спрашивать себя о том, что и как он найдет в Отрадном. Чем ближе он подъезжал, тем сильнее, гораздо сильнее (как будто нравственное чувство было подчинено тому же закону скорости падения тел в квадратах расстояний), он думал о своем доме; на последней перед Отрадным станции, дал ямщику три рубля на водку, и как мальчик задыхаясь вбежал на крыльцо дома.
После восторгов встречи, и после того странного чувства неудовлетворения в сравнении с тем, чего ожидаешь – всё то же, к чему же я так торопился! – Николай стал вживаться в свой старый мир дома. Отец и мать были те же, они только немного постарели. Новое в них било какое то беспокойство и иногда несогласие, которого не бывало прежде и которое, как скоро узнал Николай, происходило от дурного положения дел. Соне был уже двадцатый год. Она уже остановилась хорошеть, ничего не обещала больше того, что в ней было; но и этого было достаточно. Она вся дышала счастьем и любовью с тех пор как приехал Николай, и верная, непоколебимая любовь этой девушки радостно действовала на него. Петя и Наташа больше всех удивили Николая. Петя был уже большой, тринадцатилетний, красивый, весело и умно шаловливый мальчик, у которого уже ломался голос. На Наташу Николай долго удивлялся, и смеялся, глядя на нее.
– Совсем не та, – говорил он.
– Что ж, подурнела?
– Напротив, но важность какая то. Княгиня! – сказал он ей шопотом.
– Да, да, да, – радостно говорила Наташа.
Наташа рассказала ему свой роман с князем Андреем, его приезд в Отрадное и показала его последнее письмо.
– Что ж ты рад? – спрашивала Наташа. – Я так теперь спокойна, счастлива.
– Очень рад, – отвечал Николай. – Он отличный человек. Что ж ты очень влюблена?
– Как тебе сказать, – отвечала Наташа, – я была влюблена в Бориса, в учителя, в Денисова, но это совсем не то. Мне покойно, твердо. Я знаю, что лучше его не бывает людей, и мне так спокойно, хорошо теперь. Совсем не так, как прежде…
Николай выразил Наташе свое неудовольствие о том, что свадьба была отложена на год; но Наташа с ожесточением напустилась на брата, доказывая ему, что это не могло быть иначе, что дурно бы было вступить в семью против воли отца, что она сама этого хотела.
– Ты совсем, совсем не понимаешь, – говорила она. Николай замолчал и согласился с нею.
Брат часто удивлялся глядя на нее. Совсем не было похоже, чтобы она была влюбленная невеста в разлуке с своим женихом. Она была ровна, спокойна, весела совершенно по прежнему. Николая это удивляло и даже заставляло недоверчиво смотреть на сватовство Болконского. Он не верил в то, что ее судьба уже решена, тем более, что он не видал с нею князя Андрея. Ему всё казалось, что что нибудь не то, в этом предполагаемом браке.
«Зачем отсрочка? Зачем не обручились?» думал он. Разговорившись раз с матерью о сестре, он, к удивлению своему и отчасти к удовольствию, нашел, что мать точно так же в глубине души иногда недоверчиво смотрела на этот брак.
– Вот пишет, – говорила она, показывая сыну письмо князя Андрея с тем затаенным чувством недоброжелательства, которое всегда есть у матери против будущего супружеского счастия дочери, – пишет, что не приедет раньше декабря. Какое же это дело может задержать его? Верно болезнь! Здоровье слабое очень. Ты не говори Наташе. Ты не смотри, что она весела: это уж последнее девичье время доживает, а я знаю, что с ней делается всякий раз, как письма его получаем. А впрочем Бог даст, всё и хорошо будет, – заключала она всякий раз: – он отличный человек.