Указатели в Delphi. Часть первая.

Примем платформу - Intel + Windows. Считаем, что указатель 32 бита, память - линейна и непрерывна, её 4 гигабайта. Как менеджер памяти винды и делфи это разруливают, что бы оно почти так было в реальном приложении - это их проблемы. За это им уплачено.
Тогда всё просто. Есть т.н. ячейки памяти. Их, соответственно, 4 с немногим миллиарда. Они пронумерованы с нулевой по 4-х миллиардную. Все ячейки - 8-ми битные (1 байт).
Допустим, есть 32-х битная переменная i, первый байт из четырёх которой лежит в ячейке (по адресу) номер 54564786.
Допустим, также есть некоторая переменная p типа pointer. Она - 32-х битная, то есть занимает 4 байта. И лежит где-то в этой же памяти.
Так вот, если в переменную p записать число 54564786, это и будет указатель на переменную i. Затем, ‘получив’ число 54564786 из переменной p можно добраться до переменной i, ‘взяв’ данные по адресу 54564786 - операция называется ‘разыменовывание указателя’.

Nil.

Изначально в инициализированных переменных содержаться нули. Если в переменную p до того, как из неё будут читать, ничего не писали, то говорят, что указатель не инициализирован. Т.е. указывает ‘в никуда’, хотя на самом деле указывает на 0-ю ячейку). Если попробовать разыменовать указатель, который указывает на ячейку номер 0, это приведет к исключению.

Как это работает.

Была создана специальная область памяти - ловушка (64 кб), находящаяся в самом начале адресного пространства. Т.е. от ячейки номер 0 и выше. Создана, что бы ловить ошибки при работе с неинициализированными или неверно инициализированными указателями. При попытке доступа в эту область происходит исключение.

Виды указателей.

Бывают двух видов - типизированные и нетипизированные. Нетипизированный - это обычный Pointer. Типизированные - все остальные. Например, PChar - указатель на Char. Разницы между ними принципиальной нет. Это те же 4 байта, в которые записан адрес переменной. Только, например, в случае PChar, это может быть не любая переменная, а только переменная типа Char.
Реализуется это на уровне компилятора. После того, как компилятор собрал проект в экзешник, информация о том, что p - это был указатель на Byte, или на Char, или на Integer, нигде не сохраняется.

Естественно, в памяти переменную типа Char от переменной типа Byte отличить невозможно. Соответственно, указатели PByte и PChar (как и любые другие) в памяти - это совершенно одинаковые и ничем не выдающиеся переменные.

Метки: ,

Оставить комментарий