Почему я получаю ошибку сегментации, если я печатаю содержимое этой ячейки памяти - PullRequest
2 голосов
/ 24 октября 2011

Предположим, я делаю следующее int *p = 1; printf("%d", *p);

Я получаю сегфо. Теперь, насколько я понимаю, эта ячейка памяти 1 находится в адресном пространстве моей программы. Почему должна быть проблема с чтением этой области памяти?

Ответы [ 5 ]

4 голосов
/ 24 октября 2011

Ваш указатель не указывает на что-либо действительное.Все, что вам нужно сделать, это присвоить значение 1 указателю на int, но 1 не является допустимым местом в памяти.

Единственный действительный способ получить значение указателя - это либо взять адрес-переменной переменной или вызовом функции выделения:

int a;
int * p1 = &a; // OK
int * p2 = malloc(sizeof(int));  // also OK

*p1 = 2;
*p2 = 3;

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

Практически современныйОперационные системы обычно имеют умный диспетчер виртуальной памяти, который должен запрашивать память, когда и когда это необходимо, и если памяти по адресу 1 еще нет на зафиксированной странице, вы на самом деле получите сообщение об ошибке ОС.Если вы попытаетесь указать значение указателя возле какого-либо фактического адреса, вы можете не получить сообщение об ошибке (возможно, пока не выйдете за границы страницы).

3 голосов
/ 24 октября 2011

Правильный ответ на этот вопрос будет зависеть от ряда факторов. Однако вполне вероятно, что адрес 0x00000001 (стр. 0) не сопоставлен и / или не защищен от чтения.

Как правило, адреса в диапазоне страниц 0 запрещены пользовательским приложением по той или иной причине. Даже в пространстве ядра (в зависимости от процессора) адреса на странице 0 часто защищены и требуют, чтобы страница была сопоставлена ​​и доступ был разрешен.

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

2 голосов
/ 24 октября 2011

Нет, адрес 1 не находится в адресном пространстве вашей программы.Вы пытаетесь получить доступ к сегменту, который вам не принадлежит, и получаете ошибку сегментации.

2 голосов
/ 24 октября 2011

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

1 голос
/ 24 октября 2011

Вы пытаетесь напечатать 1, а не ячейку памяти.1 не является допустимой ячейкой памяти.Чтобы распечатать фактическую ячейку памяти, выполните:

printf("%p", p);

Обратите внимание на% p, как указал icktoofay.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...