Чи можуть кілька покажчиків посилатися на ту саму змінну в C?
Це особливість мови C, яка часто збиває з пантелику новачків, але здається магією, як тільки стає зрозумілою: ви можете мати безліч покажчиків, що вказують на ту саму адресу пам’яті.
Розглянемо такий сценарій. Ви оголошує цілісну змінну i. Потім оголошуєте три покажчики p, q та r. Ви надаєте їм всю адресу змінної i.
`
Подивіться на останній рядок. r не повинен знати про i безпосередньо. Він просто вказує туди, куди вказує p. А p вказує на i. Отже, r також вказує на i.
Оператор присвоювання тут копіює адресу, а чи не значення. Коли ви виконуєте r = p, ви не копіюєте ціле число, що міститься в i. Ви копіюєте адресу пам’яті, яка зберігається в p.
Після виконання цього коду у i по суті з’являється чотири імені. Ви можете звертатися до неї через i. Ви можете звертатися до неї через ‘p’. Ви можете звертатися до неї через q. Або ви можете звертатися до неї через ‘ r’.
Технічних обмежень на кількість покажчиків, які можна таким чином накопичити, немає.
Чому це важливо
Це не просто академічний синтаксис. Це змінює ваше уявлення про потік даних.
У мовах із строгими об’єктними посиланнями копіювання об’єкта часто створює новий екземпляр у пам’яті. C копіювання покажчика дешево. Це просто адреса пам’яті. Швидко. Мало.
Це дозволяє різним частинам вашого коду маніпулювати одними й тими самими даними без дублювання. Змініть *p, і *q відразу побачить цю зміну.
Ви створюєте псевдоніми пам’яті.
Ризик виникнення псевдонімів
Тут «крута особливість» перетворюється на недолік.
Якщо p, q і r всі вказують на i, будь-який з них може змінити i.
`
Тепер i дорівнює 10. *q дорівнює 10. *r дорівнює 10.
Але що, якщо ви забудете, що r також стежить за i? Ви можете припустити, що i стабільна, тому що ви не чіпали її безпосередньо. Ви торкнулися тільки *q.
Це загальний ресурс. А загальні ресурси – це місце, де живуть стани гонки (race conditions) та несподівані перезаписи даних.
Як запобігти ненавмисним побічним ефектам
Якщо ви хочете переконатися, що один покажчик не перезапише дані, призначені для іншого, використовуйте const.
`
Тепер r може читати i. Він може вказувати на неї. Але не може її змінювати.
`
Таким чином ви встановлюєте межі в мові, яка довіряє вам керування пам’яттю вручну.
Де це застосовується у системному програмуванні
Цей шаблон повсюди у системному коді.
Структури ядра часто мають кілька покажчиків на той самий блок управління. Драйвери пристроїв відображають ті самі апаратні регістри на різні логічні імена.
Розуміння того, що покажчики – це просто мітки для адрес, допомагає вам налагоджувати ці проблеми. Коли пам’ять ушкоджується, відстежуйте вказівники. Хто ще




































