Что такое ошибка сегментации? Различен ли он в C и C ++? Как связаны ошибки сегментации и висячие указатели?
c++
c
segmentation-fault
Раджендра Уппал
источник
источник
NullPointerException
.Ответы:
Ошибка сегментации - это особая ошибка, вызванная доступом к памяти, которая «не принадлежит вам». Это вспомогательный механизм, который не дает вам повредить память и вводить трудно исправляемые ошибки памяти. Всякий раз, когда вы получаете segfault, вы знаете, что делаете что-то не так с памятью - обращаетесь к переменной, которая уже была освобождена, записываете в доступную только для чтения часть памяти и т. Д. Ошибка сегментации практически одинакова в большинстве языков, которые позволяют вам связываться с В управлении памятью нет принципиальной разницы между ошибками в C и C ++.
Есть много способов получить segfault, по крайней мере на языках более низкого уровня, таких как C (++). Распространенный способ получить segfault - разыменовать нулевой указатель:
Другая ошибка происходит, когда вы пытаетесь записать часть памяти, которая была помечена как доступная только для чтения:
Свисающий указатель указывает на то, что больше не существует, как здесь:
Указатель
p
болтается, потому что он указывает на символьную переменную,c
которая перестала существовать после окончания блока. И когда вы попытаетесь разыменовать висячий указатель (например*p='A'
), вы, вероятно, получите segfault.источник
c
это локально, это означает, что он был помещен в стек после{
и выскочил из него после}
. висячий указатель - это просто ссылка на смещение, которое теперь находится вне стека. вот почему изменение его в простой программе никогда не вызовет никакого сбоя. с другой стороны, это может привести к segfault в более сложном случае, когда другие вызовы функций могут привести к росту стека и содержанию данных, на которые указывает свисающий указатель. запись в эти данные (локальные переменные) приведет к неопределенному поведению (segfault & Co)SIGSEGV
, поэтому я не ожидаю, что такой сигнал искажается стеком.Стоит отметить, что ошибка сегментации не вызвана прямым доступом к другой памяти процесса (это то, что я иногда слышу), поскольку это просто невозможно. С виртуальной памятью каждый процесс имеет свое собственное виртуальное адресное пространство, и нет никакого способа получить доступ к другому, используя любое значение указателя. Исключением из этого могут быть общие библиотеки, которые представляют собой одно и то же физическое адресное пространство, сопоставленное (возможно) разным виртуальным адресам и памяти ядра, которая даже отображается одинаково в каждом процессе (я думаю, что во избежание сброса TLB на syscall). И такие вещи, как shmat;) - это то, что я считаю «косвенным» доступом. Однако можно проверить, что они обычно расположены далеко от кода процесса, и мы обычно можем получить к ним доступ (вот почему они есть,
Тем не менее, ошибка сегментации может возникать в случае неправильного доступа к нашей собственной (процессной) памяти (например, при попытке записи в недоступное для записи пространство). Но наиболее распространенной причиной этого является доступ к той части виртуального адресного пространства, которая вообще не сопоставлена с физической.
И все это в отношении систем виртуальной памяти.
источник
Ошибка сегментации вызвана запросом на страницу, которую процесс не указал в своей таблице дескрипторов, или неправильным запросом на страницу, которую он перечислил (например, запрос на запись на странице только для чтения).
Висячий указатель - это указатель, который может указывать или не указывать на допустимую страницу, но указывает на «неожиданный» сегмент памяти.
источник
Честно говоря, как упоминали другие авторы, в Википедии есть очень хорошая статья на эту тему, так что загляните туда. Этот тип ошибки очень распространен и часто называется другими вещами, такими как нарушение прав доступа или общая ошибка защиты.
Они ничем не отличаются в C, C ++ или любом другом языке, который позволяет указатели. Такие ошибки обычно вызываются указателями, которые
источник
Согласно википедии:
источник
Ошибка сегментации также вызвана аппаратными сбоями, в данном случае памятью ОЗУ. Это менее распространенная причина, но если вы не нашли ошибку в своем коде, возможно, вам поможет memtest.
Решение в этом случае изменить оперативную память.
редактировать:
Здесь есть ссылка: Ошибка сегментации по аппаратному обеспечению
источник
Ошибка сегментации возникает, когда процесс (запущенный экземпляр программы) пытается получить доступ к адресу памяти только для чтения или диапазону памяти, который используется другим процессом, или получить доступ к несуществующему (недействительному) адресу памяти. Проблема с висячей ссылкой (указателем) означает, что при попытке доступа к объекту или переменной, содержимое которой уже удалено из памяти, например:
источник
Страница Wikipedia Segmentation_fault содержит очень хорошее описание, просто указывая причины и причины. Загляните в вики для подробного описания.
В вычислительной технике ошибка сегментации (часто сокращенная до segfault) или нарушение доступа - это ошибка, возникающая от оборудования с защитой памяти, уведомляющего операционную систему (ОС) о нарушении доступа к памяти.
Ниже приведены некоторые типичные причины ошибки сегментации:
Это, в свою очередь, часто вызвано ошибками программирования, которые приводят к неправильному доступу к памяти:
Разыменование или присвоение неинициализированному указателю (дикий указатель, который указывает на случайный адрес памяти)
Разыменование или присвоение освобожденному указателю (висячий указатель, который указывает на память, которая была освобождена / освобождена / удалена)
Переполнение буфера.
Переполнение стека.
Попытка выполнить программу, которая не компилируется правильно. (Некоторые компиляторы выводят исполняемый файл, несмотря на наличие ошибок во время компиляции.)
источник
Проще говоря: ошибка сегментации - это операционная система, посылающая программе сигнал о том, что она обнаружила несанкционированный доступ к памяти и преждевременно завершает работу программы, чтобы предотвратить повреждение памяти.
источник
«Ошибка сегментации» означает, что вы пытались получить доступ к памяти, к которой у вас нет доступа.
Первая проблема с вашими аргументами главного. Основная функция должна быть
int main(int argc, char *argv[])
, и вы должны проверить, что argc по крайней мере 2, прежде чем получить доступ к argv [1].Кроме того, поскольку вы передаете float в printf (который, кстати, преобразуется в double при переходе в printf), вы должны использовать спецификатор формата% f. Спецификатор формата% s предназначен для строк (символьные массивы, оканчивающиеся на \ 0).
источник
Ошибка сегментации или нарушение доступа возникает, когда программа пытается получить доступ к ячейке памяти, которая не существует, или пытается получить доступ к ячейке памяти способом, который не разрешен.
Здесь я [1000] не существует, поэтому происходит ошибка.
Причины ошибки сегментации:
источник
В ответах есть несколько хороших объяснений «ошибки сегментации», но поскольку в случае ошибки сегментации часто возникает дамп содержимого памяти, я хотел бы поделиться тем, где взаимосвязь между частью «сбрасывать ядро» в ошибке сегментации (ядро сбрасывается) и память приходит от:
Взято отсюда .
источник
Существует достаточно определений ошибок сегментации, я хотел бы привести несколько примеров, с которыми я сталкивался во время программирования, что может показаться глупой ошибкой, но потраченной впустую много времени.
Вы можете получить ошибку сегментации в нижнем регистре, в то время как несоответствие типа аргумента в printf
#include<stdio.h> int main(){
int a = 5; printf("%s",a); return 0; }
вывод :
Segmentation Fault (SIGSEGV)
когда вы забыли выделить память для указателя, но пытаетесь его использовать.
вывод :
Segmentation Fault (SIGSEGV)
источник
Простой смысл в
Segmentation fault
том, что вы пытаетесь получить доступ к памяти, которая не принадлежит вам.Segmentation fault
происходит, когда мы пытаемся читать и / или записывать задачи в области памяти, доступной только для чтения, или пытаемся освободить память. Другими словами, мы можем объяснить это как своего рода повреждение памяти.Ниже я упоминаю распространенные ошибки программистов, которые приводят к
Segmentation fault
.scanf()
неправильно (забыл поставить&
).printf()
иscanf()
'источник