Что такое segmentation fault?

Что такое segmentation fault? Различие в C и C ++? Как связаны связанные с сегментацией ошибки и оборванные указатели?

11 Solutions collect form web for “Что такое segmentation fault?”

Ошибка сегментации – это особый вид ошибки, вызванный доступом к памяти, которая «не принадлежит вам». Это вспомогательный механизм, который мешает вам разлагать память и вводить жесткие ошибки памяти. Всякий раз, когда вы получаете segfault, вы знаете, что делаете что-то не так с памятью – доступ к переменной, которая уже была освобождена, запись в часть только для чтения в памяти и т. Д. Ошибка сегментации по сути одинакова на большинстве языков, которые позволяют вам возиться с управления памятью, нет принципиальной разницы между segfaults в C и C ++.

Существует много способов получить segfault, по крайней мере, на языках более низкого уровня, таких как C (++). Общим способом получения segfault является разыменование нулевого указателя:

 int *p = NULL; *p = 1; 

Другой segfault случается, когда вы пытаетесь записать часть памяти, которая была помечена как доступная только для чтения:

 char *str = "Foo"; // Compiler marks the constant string as read-only *str = 'b'; // Which means this is illegal and results in a segfault 

Висячий указатель указывает на вещь, которая больше не существует, например здесь:

 char *p = NULL; { char c; p = &c; } // Now p is dangling 

Указатель p зависает, потому что он указывает на символьную переменную c которая перестала существовать после завершения блока. И когда вы пытаетесь разыменовать висячий указатель (например, *p='A' ), вы, вероятно, получите segfault.

Стоит отметить, что segmentation fault не вызвана прямым доступом к другой памяти процесса (это то, что я иногда слышу), поскольку это просто невозможно. С виртуальной памятью каждый процесс имеет собственное виртуальное адресное пространство, и нет доступа к другому, используя любое значение указателя. Исключение из этого могут быть разделяемые библиотеки, которые представляют собой одно и то же физическое адресное пространство, сопоставляемое (возможно) с разными виртуальными адресами и памятью ядра, которые, как я думаю, даже сопоставляются одинаково в каждом процессе (во избежание TLB-промывки в syscall). И такие вещи, как shmat;) – вот что я считаю «косвенным» доступом. Тем не менее, можно проверить, что они, как правило, расположены далеко от кода процесса, и мы обычно можем получить к ним доступ (именно поэтому они есть, тем не менее доступ к ним ненадлежащим образом приведет к ошибке сегментации).

Тем не менее, segmentation fault может произойти в случае неправильного доступа к нашей собственной (технологической) памяти (например, попытка записи в незаписываемое пространство). Но наиболее распространенной причиной этого является доступ к части виртуального адресного пространства, которое вообще не отображается на физическое.

И все это в отношении систем виртуальной памяти.

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

Висячий указатель – это указатель, который может или не может указывать на действительную страницу, но указывает на «неожиданный» сегмент памяти.

Честно говоря, как отмечали другие плакаты, у Википедии есть очень хорошая статья об этом, так что смотрите там. Этот тип ошибок очень распространен и часто называется другими вещами, такими как Нарушение прав доступа или Общей защиты.

Они ничем не отличаются на C, C ++ или любом другом языке, который позволяет указывать. Такие ошибки обычно вызваны указателями, которые

  1. Используется перед правильной инициализацией
  2. Используется после того, как память, на которую указывает точка, была перераспределена или удалена.
  3. Используется в индексированном массиве, где индекс находится за пределами границ массива. Обычно это происходит только тогда, когда вы выполняете математику указателей на традиционных массивах или c-строках, а не на основе STL / Boost (на C ++).

В то время как ответ Zoul объясняет, что такое segmentation fault, я обнаружил, что такие ошибки могут быть особенно трудно поймать, особенно если вы новичок в языках с низким уровнем, например C ++ или C. Вот некоторые из распространенных способов получить segmentation fault в вашей программе:

Неправильная строка управления форматом в выражениях printf или scanf

Строка управления форматом должна иметь одинаковое количество спецификаторов преобразования ( %s , %d и т. Д.), scanf printf или scanf имеют аргументы для печати или чтения. То же самое относится к fprintf и fscanf .

Не использовать & для аргументов scanf

Функция scanf принимает в качестве аргумента строку управления форматом и адреса переменных, в которых она будет помещать данные, которые она считывает. Оператор & (адрес) используется для указания адреса переменной.

Ссылки на массив вне границ

Убедитесь, что вы не нарушили границы любого массива, который вы используете; т. е. вы не индексировали массив со значением, меньшим, чем индекс его самого нижнего элемента, или больше, чем индекс его самого высокого элемента. Valgrind может пригодиться для обнаружения таких ссылок – вы можете использовать valgrind с --tool=exp-sgcheck .

Доступ к неинициализированным указателям

Перед доступом к переменной указателя должен быть присвоен действительный адрес. Убедитесь, что вы указали все указатели на допустимую область памяти.

Неправильное использование операторов & (адрес) и * (разыменование)

Вы должны быть осторожны при их использовании, особенно при передаче параметров по ссылке / с помощью указателей.

Ограничения Shell

Иногда ошибки сегментации не вызваны ошибками в программе, а вызваны тем, что ограничения системной памяти установлены слишком низко. Обычно это ограничение на размер стека вызывает такую ​​проблему (переполнение стека). Чтобы проверить пределы памяти, используйте команду ulimit в bash .

Отладка с использованием gdb

Вы можете использовать gdb отладчика, чтобы просмотреть обратную линию core файла, сбрасываемого вашей программой. Всякий раз, когда программы segfault, они обычно выгружают содержимое памяти во время сбоя в core файл ( core dumped ). Скомпилируйте свою программу с помощью флага -g , запустите в gdb и используйте bt (backtrace).

Согласно википедии:

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

Ошибка сегментации также вызвана аппаратными сбоями, в этом случае память памяти RAM. Это менее распространенная причина, но если вы не нашли ошибку в своем коде, возможно, memtest может вам помочь.

Решение в этом случае изменит ОЗУ.

редактировать:

Здесь есть ссылка: segmentation fault по аппаратным средствам

Ошибка сегментации возникает, когда процесс (исполняемый экземпляр программы) пытается получить доступ к адресу памяти только для чтения или диапазону памяти, который используется другим процессом или к доступу к несуществующему (недопустимому) адресу памяти. Ошибка ссылки (указатель) означает, что попытка доступа к объекту или переменной, содержимое которой уже было удалено из памяти, например:

 int *arr = new int[20]; delete arr; cout<  

На странице Segmentation_fault Википедии есть очень приятное описание, просто указывая причины и причины. Посмотрите на wiki для подробного описания.

При вычислении segmentation fault (часто сокращается до segfault) или нарушение прав доступа – это ошибка, вызванная аппаратным обеспечением с защитой памяти, уведомление операционной системы (ОС) о нарушении доступа к памяти.

Ниже приводятся некоторые типичные причины ошибки сегментации:

  • Разметка NULL-указателей – это специальное приложение для управления памятью
  • Попытка доступа к несуществующему адресу памяти (внешнему пространству процесса)
  • Пытаясь получить доступ к памяти, у программы нет прав (таких как структуры ядра в контексте процесса)
  • Попытка написать постоянную память (например, сегмент кода)

Это, в свою очередь, часто вызвано ошибками программирования, которые приводят к недопустимому доступу к памяти:

  • Выделение или назначение неинициализированному указателю (дикий указатель, указывающий на случайный адрес памяти)

  • Выделение или назначение освобожденному указателю (оборванный указатель, указывающий на память, которая была освобождена / освобождена / удалена)

  • Переполнение буфера.

  • Переполнение стека.

  • Попытка выполнить программу, которая не компилируется правильно. (Некоторые компиляторы выдают исполняемый файл, несмотря на наличие ошибок времени компиляции.)

Простыми словами: segmentation fault – это операционная система, посылающая сигнал программе, заявив, что она обнаружила незаконный доступ к памяти и преждевременно завершает работу программы, чтобы предотвратить повреждение памяти.

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

  /* "Array out of bounds" error valid indices for array foo are 0, 1, ... 999 */ int foo[1000]; for (int i = 0; i < = 1000 ; i++) foo[i] = i; 

Здесь i [1000] не существует, поэтому происходит segfault.

Причины возникновения сегментации:

 it arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access. De-referencing NULL pointers – this is special-cased by memory management hardware. Attempting to access a nonexistent memory address (outside process's address space). Attempting to access memory the program does not have rights to (such as kernel structures in process context). Attempting to write read-only memory (such as code segment). 
Interesting Posts

Есть ли причина использовать Кукольный рядом с Докером?

Установите LAN для приоритета сети перед тем, как Wi-Fi в Windows 7

Поверните одну строку в несколько строк в Excel

Как исправить значки и текст в программах, которые неожиданно увеличились, в Windows 8.1?

Как я могу создать резервную копию всей установки программы, а не просто вручную создавать резервные копии отдельных файлов?

Как сделать снимок экрана в Windows 7 и автоматически создать файл скриншотов на рабочем столе, таком как Mac?

Монтирование SSH / SFTP на Windows 7

Отключить SMART в Windows 7?

Как установить прошивку openfwwf и измененный драйвер b43 с помощью openwrt

Можете ли вы отключить кеш шрифтов VLC?

Синхронизация папок вне Dropbox с использованием символических ссылок и соединений

Как добавить панель отключения на начальный экран?

Изменение размера окна iTerm 2

Создание сочетаний клавиш Spotify

Как я могу узнать путь к текущему изображению рабочего стола, для Windows 8

Давайте будем гением компьютера.