Ошибка сегментации в программе 'C' - PullRequest
0 голосов
/ 08 июня 2018

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

Я не вижу ошибки сегментации с этой программой -

 int main (void)
    {
    int c = 6;

    *(&c + 1000) = 5;

    printf ("0x%llx - %d\n", (unsigned long)&c, c);

    return 0;
    }

, которая выводит:

$ gcc segmentationFault.c
$ ./a.out
0x7ffc2f709b5c - 6
$

Но я получаю ошибку сегмента с кодом ниже -

int main (void)
{
    int c = 6;

    *(&c + 3000) = 5;

    printf ("0x%llx - %d\n", (unsigned long)&c, c);

    return 0;
}

, который производит:

$ gcc segmentationFault.c
$ ./a.out
Segmentation fault (core dumped)
$

Любое объяснение, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

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

Для части языка C: вы вызываете Undefined Behavior, потому что c является единственнымпеременная, &c - указатель на начало массива размером 1. Поэтому разыменование &c + i - это UB для любого i != 0.UB означает, что с языковой точки зрения может произойти все, что угодно - от возврата int до окончательного состояния машины.Здесь больше ничего нельзя сказать.

Для части реализации ошибка сегмента - это попытка прочитать адрес, который находится на странице, которая не привязана к процессу в системе, которая предоставляет страницы памяти (свозможно виртуальные адреса, что означает таблицу, сопоставляющую адреса в пространстве процесса с адресами в физической памяти).В Linux /proc/{pid}/maps и /proc/{pid}/pagemaps предоставляют информацию о сопоставлении процесса.Подробнее об этом на следующих страницах SO:

0 голосов
/ 08 июня 2018

Ошибка сегментации возникает, когда ваша программа обращается к памяти, к которой у нее нет доступа.В вашем примере, c+1000 все еще может быть доступен для вашей программы, в то время как c+3000 больше нет.Однако, поскольку это неопределенное поведение, даже *(c+1) может вызвать ошибку сегментации.

...