Указатели в C: почему несколько переменных разделяют один адрес памяти

11

В C можно создать несколько указателей, которые указывают на один и тот же участок памяти. Это не ошибка. Это особенность языка.

Вы можете объявить три указателя на целые числа: p, q и r. Затем вы можете установить их все так, чтобы они указывали на одну и ту же целочисленную переменную i.

Посмотрите, что здесь происходит. p получает адрес i. q также получает адрес i. r получает то, что хранится в p. А именно — адрес i.

После выполнения этого кода возникает своеобразная ситуация. У переменной i теперь есть четыре имени. Вы можете обращаться к ней через i, *p, *q или *r. Все они ссылаются на одну и ту же область в оперативной памяти.

Как работает присваивание указателей

Когда вы присваиваете один указатель другому, вы не копируете значение, на которое они указывают. Вы копируете адрес.

r = p не копирует целое число i. Оно копирует адрес памяти, хранящийся в p. Поскольку p содержит адрес i, r теперь также содержит адрес i.

Нет ограничения на количество указателей, которые могут разделять один адрес. У вас может быть десять указателей. Или сто. Все они просто указывают на одно и то же.

Почему это важно

Это поведение меняет ваше представление о данных. Одна переменная в памяти может иметь много псевдонимов. Если вы измените значение через один указатель, каждый другой указатель увидит это изменение.

Теперь i равно 10. *q равно 10. *r равно 10. Все они смотрят на одни и те же данные.

Это полезно. Это позволяет передавать ссылки на функции без копирования больших структур. Это позволяет различным частям вашего кода работать с одними и теми же данными. Но это также означает, что нужно быть осторожным. Изменение через один указатель может повлиять на другие.

Распространённые заблуждения

Некоторые начинающие разработчики думают, что присваивание указателей копирует данные. Это не так. Копируется адрес.

Другие задаются вопросом, существует ли ограничение. Его нет. Язык позволяет создавать столько указателей, сколько вам нужно. Компилятор не препятствует этому.

Итог

Несколько указателей могут указывать на один и тот же адрес. Это стандартное поведение в C. Вы можете присваивать указатели друг другу. Копируется адрес, а не значение. Переменная остаётся одной и той же. Просто увеличивается количество её «имён».

«Нет ограничений на количество указателей, которые могут хранить (и, следовательно, указывать) на один и тот же адрес.»

Эта гибкость мощна. Она требует дисциплины. Но она фундаментальна для того, как работает C. Если вы понимаете это, вы понимаете одну из ключевых концепций управления памятью в C.