(Первый вопрос - правильно ли я понимаю?)
Первое, что нужно признать, это то, что значение может вообще не сохраняться в основной памяти. Компилятор может решить сохранить его в регистре, поскольку это более оптимально. 1
Память является адресуемой по байту, поэтому CPU выбирает для моей переменной 4 непрерывных байта и сохраняет адрес в первом (или последнем) байте.
Если предположить, что компилятор решит сохранить его в основной памяти, то да, на 32-разрядной машине int
обычно составляет 4 байта, поэтому для хранения будет выделено 4 байта.
Размер этого адреса (указатель на эту переменную) составляет 4 байта в 32-битном процессоре. (Вот почему 32-разрядный процессор может использовать максимум 4 ГБ памяти - потому что существует только 2 ^ 32 разных адресов двоичной длины 32)
Обратите внимание, что ширина int
и ширина указателя не обязательно должны быть одинаковыми, поэтому не обязательно обязательно соединение с размером адресного пространства.
Теперь, где процессор хранит эти адреса?
В случае локальных переменных адрес эффективно жестко закодирован в самом исполняемом файле, обычно в виде смещения от указателя стека.
В случае динамически распределяемых объектов (то есть вещи, которые были malloc
-ed), программист обычно поддерживает соответствующую переменную указателя (в противном случае произошла бы утечка памяти!). Этот указатель также может быть динамически размещен (в случае сложной структуры данных), но если вы вернетесь достаточно далеко, вы в конечном итоге достигнете чего-то, что является локальной переменной. В этом случае применяется вышеуказанное правило.
Но переменные могут занимать до 4 ГБ пространства, поэтому ЦП должен иметь 4 ГБ своего собственного пространства для хранения адресов этих переменных.
Если ваша программа состоит из независимо malloc
-миллионов int
с, тогда да, вы получите столько же памяти, сколько требуется указателям. Но большинство программ не выглядят так. Обычно вы выделяете гораздо большие объекты (например, массив или большую структуру).
кэш
Особенности , где хранится , зависят от архитектуры. На современном x86 обычно имеется 2 или 3 слоя кеша между процессором и основной памятью. Но кеш не адресуется независимо; ЦП не может решить хранить int
в кеше вместо основной памяти. Скорее, кеш - это фактически избыточная копия подмножества основной памяти.
Еще одна вещь, которую следует учитывать, - это то, что компилятор обычно имеет дело с виртуальными адресами при выделении хранилища для объектов. На современном x86 они сопоставляются с физическими адресами (то есть адресами, которые соответствуют байтам физической памяти в основной памяти) с помощью выделенного оборудования вместе с поддержкой ОС.
1. Кроме того, компилятор может полностью оптимизировать его.