Указатели C (всегда) начинаются с правильной адресной памяти? - PullRequest
1 голос
/ 19 марта 2019

Указатель C (всегда) начинается с правильной адресной памяти? Например, если у меня есть следующий фрагмент кода:

int *p;
*p = 5;
printf("%i",*p); //shows 5

Почему этот кусок кода работает? Согласно книгам (которые я читал), они говорят, что указателю всегда нужна правильная адресная память, и приводят следующий и похожий пример:

int *p;
int v = 5;  
p = &v;
printf("%i",*p); //shows 5

Ответы [ 4 ]

5 голосов
/ 19 марта 2019

Указатель C (всегда) начинается с действительной памяти адресов?

Нет.

Почему этот код работает?

Код вызывает неопределенное поведение.Если кажется, что он работает в вашей конкретной системе с вашими опциями компилятора, это просто совпадение.

3 голосов
/ 19 марта 2019

Нет. Неинициализированные локальные переменные имеют неопределенные значения, и использование их в выражениях, где они оцениваются, вызывает неопределенное поведение.

2 голосов
/ 19 марта 2019

Поведение не определено.Компилятор переменного тока может оптимизировать доступ к указателю, отмечая, что в fact p не используется только объект *p, и заменить *p на qи эффективно создать программу, которая соответствует этому исходному коду:

#include <stdio.h>

int main(void) {
    int q = 5;
    printf("%i", q); //shows 5
}

Таков случай, когда я компилирую программу с GCC 7.3.0 и -O3 switch - без сбоев.Я получаю сбой, если скомпилирую без оптимизации.Обе программы соответствуют стандарту интерпретации кода, а именно, что разыменование указателя, который не указывает на действительный объект, имеет неопределенное поведение .

0 голосов
/ 19 марта 2019

номер

В старое время было принято инициализировать указатель на выбранные адреса памяти (например, связанные с оборудованием).

char *start_memory buffer = (char *)0xffffb000;

Компилятор не может найти действительный адрес. Это связано с актерским составом, поэтому это обман.

Рассмотрим

static int *p;

p будет иметь значение NULL, которое не указывает на действительный адрес (Linux, но в ядре это делает недействительным такой адрес, другие ОС могут использовать память на &NULL для хранения некоторых данных.

Но вы также можете создавать инициализированные переменные, например, с неопределенными начальными значениями (что, вероятно, неправильно).

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