Всегда ли sizeof (некоторый указатель) равен четырем? - PullRequest
210 голосов
/ 30 декабря 2008

Например: sizeof(char*) возвращает 4. Как и int*, long long*, все, что я пробовал. Есть ли исключения из этого?

Ответы [ 17 ]

178 голосов
/ 30 декабря 2008

Вы получаете гарантию, что sizeof(char) == 1. Других гарантий, в том числе sizeof(int *) == sizeof(double *).

, нет.

На практике указатели будут иметь размер 2 в 16-битной системе (если вы можете его найти), 4 в 32-битной системе и 8 в 64-битной системе, но при использовании ничего не нужно на заданный размер.

36 голосов
/ 14 января 2009

Даже на простой 32-разрядной платформе x86 вы можете получить указатели разных размеров, попробуйте это на примере:

struct A {};

struct B : virtual public A {};

struct C {};

struct D : public A, public C {};

int main()
{
    cout << "A:" << sizeof(void (A::*)()) << endl;
    cout << "B:" << sizeof(void (B::*)()) << endl;
    cout << "D:" << sizeof(void (D::*)()) << endl;
}

В Visual C ++ 2008 я получаю 4, 12 и 8 для размеров функции указателя на член.

Раймонд Чен говорил об этом здесь .

29 голосов
/ 30 декабря 2008

Просто еще одно исключение из уже опубликованного списка. На 32-битных платформах указатели могут занимать 6, , а не 4 , байты:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char far* ptr; // note that this is a far pointer
    printf( "%d\n", sizeof( ptr));
    return EXIT_SUCCESS;
}

Если вы скомпилируете эту программу с помощью Open Watcom и запустите ее, вы получите 6, потому что поддерживаемые ею дальние указатели состоят из 32-битного смещения и 16-битных значений сегмента

24 голосов
/ 30 декабря 2008

если вы компилируете для 64-битной машины, то это может быть 8.

17 голосов
/ 31 декабря 2008

Технически говоря, стандарт C гарантирует, что sizeof (char) == 1, а остальное зависит от реализации. Но на современных архитектурах x86 (например, на чипах Intel / AMD) это вполне предсказуемо.

Возможно, вы слышали, что процессоры описываются как 16-разрядные, 32-разрядные, 64-разрядные и т. Д. Обычно это означает, что процессор использует N-разрядные числа для целых чисел. Поскольку указатели хранят адреса памяти, а адреса памяти являются целыми числами, это фактически говорит вам, сколько битов будет использоваться для указателей. sizeof обычно измеряется в байтах, поэтому код, скомпилированный для 32-разрядных процессоров, сообщит, что размер указателей равен 4 (32 бита / 8 бит на байт), а код для 64-разрядных процессоров сообщит, что размер указателей равен 8 (64 бита / 8 бит на байт). Отсюда и ограничение в 4 ГБ ОЗУ для 32-разрядных процессоров - если каждый адрес памяти соответствует байту, для адресации большего объема памяти нужны целые числа больше 32-разрядных.

6 голосов
/ 05 июня 2015

Размер указателя в основном зависит от архитектуры системы, в которой он реализован. Например, размер указателя в 32-разрядных системах составляет 4 байта (32-разрядных) и 8 байтов (64-разрядных) в 64-разрядных компьютерах. Типы битов в машине - это не что иное, как адрес памяти, который он может иметь. 32-битные машины могут иметь 2^32 адресное пространство, а 64-битные машины могут иметь до 2^64 адресное пространство. Таким образом, указатель (переменная, которая указывает на ячейку памяти) должен иметь возможность указывать на любой адрес памяти (2^32 for 32 bit and 2^64 for 64 bit), который хранится в машине.

По этой причине мы видим размер указателя равным 4 байта на 32-битной машине и 8 байтов на 64-битной машине.

6 голосов
/ 30 декабря 2008

В дополнение к разнице в 16/32/64 битов могут происходить и более странные вещи.

Были машины, где sizeof (int *) будет одним значением, вероятно, 4, но где sizeof (char *) больше. Машины, которые естественным образом адресуют слова вместо байтов, должны «дополнить» символьные указатели, чтобы указать, какая часть слова вам действительно нужна, чтобы правильно реализовать стандарт C / C ++.

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

5 голосов
/ 17 июля 2013

8-битные и 16-битные указатели используются в большинстве низкопрофильных микроконтроллеров. Это означает, что каждая стиральная машина, микро, холодильник, старые телевизоры и даже автомобили.

Можно сказать, что это не имеет ничего общего с программированием в реальном мире. Но вот один пример из реальной жизни: Arduino с оперативной памятью 1-2-4 КБ (в зависимости от чипа) с 2-байтовыми указателями.

Это недавно, дешево, доступно для всех и заслуживает написания.

4 голосов
/ 31 декабря 2008

В дополнение к тому, что люди говорили о 64-битных (или любых других) системах, существуют другие виды указателей, чем указатель на объект.

Указатель на член может быть практически любого размера, в зависимости от того, как он реализован вашим компилятором: они не обязательно даже одного размера. Попробуйте указатель на член класса POD, а затем указатель на член, унаследованный от одного из базовых классов класса с несколькими основаниями. Как весело.

3 голосов
/ 14 июля 2014

Размер указателя и int составляет 2 байта в компиляторе Turbo C на Windows 32-битной машине.

Таким образом, размер указателя зависит от компилятора. Но, как правило, большинство компиляторов реализовано для поддержки 4-байтовой переменной указателя в 32-битной и 8-байтовой переменной указателя в 64-битной машине)

Таким образом, размер указателя не одинаков на всех машинах.

...