От вопроса на Практике C тестируют от GeekInterview, почему имеет размер ptr1
2, в то время как ptr2
и ptr3
имеет размер 4?
main()
{
char near * near *ptr1;
char near * far *ptr2;
char near * huge *ptr3;
printf("%d %d %d",sizeof(ptr1),sizeof(ptr2),sizeof(ptr3));
}
Вывод: 2 4 4
При работе с архитектурами с сегментированной памятью (например, в реальном режиме x86) можно выделить три типа адресов указателей (примеры для x86 в записи сегмента: смещение):
рядом с
Сохраняет только часть смещения (которая является 16-битным) - при разрешении такого указателя текущее смещение сегмента данных будет использоваться как адрес сегмента.
far
Сохраняет адрес сегмента и смещения (каждый по 16 бит), тем самым определяя абсолютный физический адрес в памяти.
огромный
То же, что и дальний указатель, но может быть нормализован, то есть 0000: FFFF + 1
будет соответствующим образом перенесен на следующий адрес сегмента.
В современных ОС это больше не имеет значения, поскольку модель памяти обычно плоская, с использованием виртуальной памяти вместо прямой адресации к физической памяти (по крайней мере, в приложениях третьего кольца).
Потому что вы используете ближние указатели вместо дальних указателей . В этом случае дальний указатель требует двух 16-битных адресов.
(Спецификатор «огромный» - нестандартный синтаксис дальнего указателя для обработки некоторых конкретных случаев дальнего указателя ...)