Ради аргумента скажем, что c
занимает один байт в памяти. Также предположим, что int
занимает 4 байта в памяти.
Выражение int * pn = (int *) &c;
делает указатель на 4-байтовую память , указывающую на однобайтовую память. Пока проблем нет (указатели могут указывать куда угодно).
Оператор: *pn = 0x12345678;
присваивает 4-байтовое значение одной ячейке памяти (помните, что c
- это только один байт в памяти).
+---+
c: | |
+---+
+---+---+---+---+
pn-> | | | | |
+---+---+---+---+
int
требует больше места в памяти, чем вы выделили.
Изменение типа указателя не выделяет больше памяти.
Редактировать 1: возможная перезапись
Один из возможных сценариев - перезапись памяти.
100 101 102 103
+-----+-----+-----+-----+
c: | 65 | | | |
pn-> | | | | |
+-----+-----+-----+-----+
После *pn = 0x12345678;
:
100 101 102 103
+-----+-----+-----+-----+
c: | 12 | 34 | 56 | 78 |
pn-> | | | | |
+-----+-----+-----+-----+
Если перезапись не вызывает никаких исключений, вы не знаете, какие переменные расположены по адресам 101, 102 или 103. может перезаписывать другие переменные.
(приведенная выше схема предполагает макет с прямым порядком байтов).
Существуют другие сценарии ios (например, переменная c
выделяется в конце памяти), поэтому вы будете писать после конца памяти.
Поведение не определено.
Редактировать 2: Чтение - неопределенное поведение
Как правило, память содержит случайные значения (значения из других программ, значения, которые не инициализированы).
Заданная память со случайными значениями (после инициализации переменной c
):
100 101 102 103
+-----+-----+-----+-----+
c: | 65 | ?F0 | ?0D | ?CD |
pn-> | | | | |
+-----+-----+-----+-----+
Разыменование указателя pn
(как 4-байтового) количества приводит к 0x65F00DCD (Big Endian). Разыменование в платформах Little Endian: 0xCD0DF065. '?'
представляет неинициализированное значение.
Это только один из возможных сценариев. Если c
находится в последней адресуемой ячейке памяти, ваша программа может сгенерировать SEGFAULT для доступа к памяти за пределами границы.
Чтение несколько раз
Множество возможных сценариев ios , Другой сценарий заключается в том, что одно и то же местоположение читается несколько раз. Таким образом, на приведенных выше диаграммах разыменование pn
(он же *pn
) может привести к значению 0x65656565
.