Ошибка GCC, плохой код или gcc является хорошим компилятором

#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;