Байты памяти расположены непрерывно и последовательно начиная с нуля и каждый имеет свой адрес отличный на единицу, предельное значение которого в шестнадцатеричном формате представления зависит от архитектуры системы и ограничено размером оперативной памяти, адресуемой процессором.
Далеко не всегда адреса памяти начинаются с нуля. И во избежание ошибок, назначением адресов занимается компилятор в соответствии с заданной картой памяти, либо рантайм-механизм динамического распределения памяти.
Николай Веселуха
Высший разум
(382646)
Moon Late, здесь речь идёт о языках С/С++. И для людей, которые пишут на нём код установлено такое правило, которое я дал в своём ответе. Оно исключает возможность двух указателей из разных программ хранить разные адреса, которые указывают на один блок физической памяти и позволяют использовать адресную арифметику. Это концепция, и механизмы её распределения здесь ни при чём.
Указатель в C/C++ - это просто адрес ячейки оперативной памяти - точно такой же, как в ассемблере. И любые ограничения накладываются не языком, а конкретным процессором. Например, адрес слова (2 байта) должен быть чётным и т.п. Но это ограничения не языка, а конкретного железа.