Это очень распространенный тип ошибки времени выполнения для
C/C++.
Когда программа запускается и система отчетов вашей системы выдает «нарушение сегментации», это означает, что ваша программа пыталась получить доступ к области памяти, доступ к которой ей запрещен. Другими словами, вы попытались получить доступ к части памяти, которая выходит за пределы, выделенные операционной системой (Unix GNU/Linux и т. д.) для вашей программы.
Почему так происходит
Некоторые распространенные причины этой проблемы:
Неправильное использование операторов "&"(направление/адрес) и "*"
(косвенность/разыменование)
Неверная управляющая строка в операторах printf или scanf
Строки управления форматом должны иметь одинаковое количество спецификаторов преобразования (%'s)и аргументов для печати или чтения, а спецификаторы должны соответствовать типу переменной для печати или чтения. Это относится к fprintf и fscanf, а также к printf и scanf.
Забудьте использовать "&"в аргументах scanf (этот случай упоминается Elenasys)
Функция scanf принимает в качестве аргументов строку управления форматом и адреса переменных, в которые должны быть помещены считываемые данные (оператор "&"используется для указания адреса переменной). Часто забывают использовать "&"каждую переменную в вызове scanf. Пропуск "&"может привести к нарушению сегментации.
Доступ за пределы массива/вектора и т.п.: попробуйте получить доступ к нижним индексам массива со значением, меньшим, чем индекс его самого нижнего элемента, или большим, чем индекс его самого высокого элемента.
Ошибка инициализации указателя перед доступом к нему: переменной «указатель» должен быть присвоен допустимый адрес памяти.
int *ip;
std::cout << *ip << std::endl; //usar un puntero no inicializado
Попытка неправильного доступа к части памяти, даже если она доступна вашей программе.
char *str = "string";// static array de caracteres, sin nombre/id
// este array se crea en modo "read-only memory"
// como solo lectura
str[0] = 'n';
Попытка доступа к объекту или переменной, которая была удалена из памяти, например:
int *pArrI = new int[9];//solicitamos en el heap
delete[] pArrI; //eliminamos
std::cout << pArrI[1]; //intentamos acceder a una parte inexistente
В системе Unix с виртуальной памятью у каждого процесса есть области памяти, к которым он может получить доступ. Например, в Linux вы можете увидеть области виртуальной памяти (VMA) процесса, прочитав виртуальный файл /proc/<pid>/maps:
Как видите, вы получаете список областей памяти с соответствующими разрешениями ( r-read, w-write, x-execute).
Если процесс попытается получить доступ к зоне памяти, которой нет в предыдущем списке, или будет предпринята попытка доступа, для которого у него нет разрешения, MMU процессора (блок управления памятью) сгенерирует исключение, ядро обработает это исключение, обращаясь к списку выше, и, наконец, ядро отправит сигнал SIGSEGVпроцессу.
По умолчанию SIGSEGVпроцесс завершается путем создания дампа памяти .
Есть еще один связанный сигнал, SIGBUSкоторый соответствует ошибке шины. На некоторых процессорах оно будет получено SIGBUSпри попытке доступа к невыровненному адресу (например, при попытке доступа к 4-байтовому слову по адресу, не кратному 4 байтам). Другая возможная причина SIGBUSможет заключаться в том, что одна из областей соответствует физическому устройству, отображаемому в памяти, и доступ к этому физическому адресу невозможен.
Он определяется как нарушение доступа (нарушение сегмента или нарушение доступа и ошибка сегментации на английском языке) к неудачной попытке доступа к информации или программам, на просмотр или изменение которых у вас нет полномочий. Это сообщение может быть вызвано конфигурацией программного обеспечения, программистами или аппаратным сбоем, причем первые 2 являются наиболее распространенными.
В современных операционных системах каждый процесс имеет один или несколько сегментов системной памяти, где он может хранить и извлекать информацию. Каждый процесс может запросить больше или меньше памяти (по мере необходимости), и запрос будет распознан операционной системой и сравнен с разделом памяти, предоставленным процессу. Как правило, только процесс, запросивший память, может ее прочитать или изменить.
Нарушение прав доступа происходит, когда процесс пытается получить доступ к части памяти, выделенной другому приложению, или к неиспользуемой области памяти, не имея на это прав. Обычно это происходит в результате ошибки программирования, например, случайного указателя. Другой способ, которым может возникнуть ошибка сегментации, — это физически поврежденная память, так как какая-то программа будет записывать в память, а затем пытаться получить доступ к этим данным, но когда память выйдет из строя, данные могут быть стерты, поэтому программа будет учитывать этот адрес памяти. как пустой, то есть неиспользуемый, что выдаст ошибку.
Типичный пример того, как это может быть получено, если в следующей программе мы опускаем &:
#include <stdio.h>
int main ()
{
int i;
printf ("introduce tu edad: ");
scanf ("%d",i); //genera violación de segmento!
printf ("Miss Elena, tu edad es: , %d.\n",i);
return 0;
}
Segfault возникает, когда процесс пытается получить доступ к памяти, которая ему не принадлежит, или выполнить операцию, для которой у него нет разрешений. Общие примеры:
Попытка доступа к переменной, которая уже была освобождена.
Segmentation fault - нарушение сегмента.
Что это значит?
Это очень распространенный тип ошибки времени выполнения для
C/C++
.Когда программа запускается и система отчетов вашей системы выдает «нарушение сегментации», это означает, что ваша программа пыталась получить доступ к области памяти, доступ к которой ей запрещен. Другими словами, вы попытались получить доступ к части памяти, которая выходит за пределы, выделенные операционной системой (Unix GNU/Linux и т. д.) для вашей программы.
Почему так происходит
Некоторые распространенные причины этой проблемы:
"&"
(направление/адрес) и"*"
(косвенность/разыменование)Строки управления форматом должны иметь одинаковое количество спецификаторов преобразования
(%'s)
и аргументов для печати или чтения, а спецификаторы должны соответствовать типу переменной для печати или чтения. Это относится к fprintf и fscanf, а также к printf и scanf."&"
в аргументах scanf (этот случай упоминается Elenasys)Функция scanf принимает в качестве аргументов строку управления форматом и адреса переменных, в которые должны быть помещены считываемые данные (оператор
"&"
используется для указания адреса переменной). Часто забывают использовать"&"
каждую переменную в вызове scanf. Пропуск"&"
может привести к нарушению сегментации.Ошибка инициализации указателя перед доступом к нему: переменной «указатель» должен быть присвоен допустимый адрес памяти.
Попытка неправильного доступа к части памяти, даже если она доступна вашей программе.
Попытка доступа к объекту или переменной, которая была удалена из памяти, например:
В системе Unix с виртуальной памятью у каждого процесса есть области памяти, к которым он может получить доступ. Например, в Linux вы можете увидеть области виртуальной памяти (VMA) процесса, прочитав виртуальный файл
/proc/<pid>/maps
:Как видите, вы получаете список областей памяти с соответствующими разрешениями (
r
-read,w
-write,x
-execute).Если процесс попытается получить доступ к зоне памяти, которой нет в предыдущем списке, или будет предпринята попытка доступа, для которого у него нет разрешения, MMU процессора (блок управления памятью) сгенерирует исключение, ядро обработает это исключение, обращаясь к списку выше, и, наконец, ядро отправит сигнал
SIGSEGV
процессу.По умолчанию
SIGSEGV
процесс завершается путем создания дампа памяти .Есть еще один связанный сигнал,
SIGBUS
который соответствует ошибке шины. На некоторых процессорах оно будет полученоSIGBUS
при попытке доступа к невыровненному адресу (например, при попытке доступа к 4-байтовому слову по адресу, не кратному 4 байтам). Другая возможная причинаSIGBUS
может заключаться в том, что одна из областей соответствует физическому устройству, отображаемому в памяти, и доступ к этому физическому адресу невозможен.Это концепция, которая обычно возникает, когда:
Ищите определение в интернете у вас: Access Violation .
Типичный пример того, как это может быть получено, если в следующей программе мы опускаем
&
:На линии:
Затем происходит нарушение прав доступа.
Segfault возникает, когда процесс пытается получить доступ к памяти, которая ему не принадлежит, или выполнить операцию, для которой у него нет разрешений. Общие примеры: