#c #pointers #memory-management
#c #указатели #управление памятью
Вопрос:
У меня есть этот код:
int *b;
b = 50;
printf("Pointer point to address: %p and also point to this value: %d", b, *b);
return 0
Я получил эту ошибку:
main.c: 6:7: предупреждение: присваивание создает указатель из целого числа без приведения [-Win-conversion]
тайм-аут: отслеживаемая команда сбросила ядро
sh: строка 1: 47524 Ошибка сегментации, тайм-аут 10 секунд основной
Я хочу напечатать значение из пятидесяти байт памяти.
Правильный ли мой код или компилятор заставит его работать.
Комментарии:
1. Компилятор всегда прав. Компилятор выдал вам предупреждение. Вы проигнорировали это, и посмотрите, что произошло. Предупреждение на самом деле довольно очевидно, и его распознает большинство программистов на C…
2. Я настоятельно рекомендую вам ознакомиться с любым базовым руководством по c, посвященным указателям и ссылкам.
3.
50
вероятно, это неправильное (жестко закодированное) значение указателя. Пожалуйста, попробуйтеint a = 50; int *b = amp;a; ...
4. Я думаю, что получаю какое-то значение из памяти, что-то вроде утечки.
5. Вы пытались прочитать адрес памяти,
50
который, вероятно, вам не принадлежит, отсюда ошибка segfault. Компилятор возразил, потому что50
это целочисленное значение, а не значение указателя, отсюда и предупреждение.
Ответ №1:
Предполагая, что вы запускаете программу на новой ОС, такой как Linux, Mac или Windows, 50 не будут байтами, расположенными по адресу 50 в вашей физической памяти ; это адрес в виртуальном пространстве.
Тогда ваш процесс (программа) имеет доступ только к очень ограниченному диапазону в этом виртуальном пространстве, из которого вряд ли будет 50 ; в этом случае ОС защищает незаконный доступ и останавливает ваш процесс (segfault) ; в любом случае вы могли бы даже получить результат, который может быть или не быть правильным, это называется неопределенным поведением, и вам лучше не полагаться в этом случае на явно работающий исполняемый файл.
Для прямого доступа к физической памяти вам необходимо либо собрать модуль ядра, либо загрузиться, например, из DOS-подобной ОС.
main.c: 6:7: предупреждение: присваивание создает указатель из целого числа без приведения [-Win-conversion]
При этом вам нужно выполнить приведение 50
как int *
, чтобы убрать предупреждение.
b = (int *)50;