Является ли sizeof (некоторый указатель) всегда равным четырем?

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

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

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

Даже на простой 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 для размеров указателей на функцию-член.

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

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

 #include  #include  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-разрядных значений сегмента

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

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

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

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

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

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

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

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

Это последнее, дешевое, доступное для всех и достойное кодирование.

Размер указателя в основном зависит от архитектуры системы, в которой она реализована. Например, размер указателя в 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-битной машине.

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

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

Из того, что я помню, он основан на размере адреса памяти. Таким образом, в системе с 32-разрядной адресной схемой sizeof будет возвращать 4, так как это 4 байта.

В общем случае sizeof (почти все) изменится при компиляции на разных платформах. На 32-битной платформе указатели всегда одного размера. На других платформах (пример 64 бит является очевидным) это может измениться.

Нет, размер указателя может варьироваться в зависимости от архитектуры. Есть множество исключений.

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

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

Поэтому размер указателя не одинаковый во всех машинах.

Причина, по которой размер вашего указателя составляет 4 байта, заключается в том, что вы компилируете 32-битную архитектуру. Как отметил Фрай Гуй, в 64-битной архитектуре вы увидите 8.

Указатель – это просто контейнер для адреса. На 32-битной машине ваш диапазон адресов составляет 32 бита, поэтому указатель всегда будет 4 байта. На 64-битной машине у вас был диапазон адресов из 64 бит, указатель будет 8 байтов.

В Win64 (Cygwin GCC 5.4) , давайте посмотрим нижеприведенный пример:

Сначала проверьте следующую структуру:

 struct list_node{ int a; list_node* prev; list_node* next; }; struct test_struc{ char a, b; }; 

Ниже приведен тестовый код:

 std::cout<<"sizeof(int): "< 

Выходной сигнал ниже:

 sizeof(int): 4 sizeof(int*): 8 sizeof(double): 8 sizeof(double*): 8 sizeof(list_node): 24 sizeof(list_node*): 8 sizeof(test_struc): 2 sizeof(test_struc*): 8 

Вы можете видеть, что в 64-битном sizeof(pointer) равен 8 .

Для полноты и исторического интереса в 64-битном мире существовали различные соглашения о платформе размеров длинного и длинного длинного типа LLP64 и LP64, в основном между системами Unix и Windows. Старый стандарт ILP64 также сделал int = 64-бит.

Microsoft поддерживала LLP64, где longlong = 64 бит в ширину, но долгое время оставалось на 32, для упрощения переноса.

 Type ILP64 LP64 LLP64 char 8 8 8 short 16 16 16 int 64 32 32 long 64 64 32 long long 64 64 64 pointer 64 64 64 

Источник: https://stackoverflow.com/a/384672/48026

  • Функция для динамического выделения матрицы
  • Как связаны iteratorы и указатели?
  • Как я могу индексировать массив MATLAB, возвращаемый функцией, не назначая сначала локальную переменную?
  • Каковы операторы Pointer-to-Member -> * и. * В C ++?
  • Является ли указатель «один-на-конец» типа не-массива допустимым понятием в C ++?
  • Почему в C ++ не существует ссылки на член?
  • Не удается найти модуль 'angleular2 / angular2'
  • значение «ссылки» и «разыменование»,
  • Как избежать утечек памяти при использовании вектора указателей на динамически выделенные объекты в C ++?
  • Возвращающий указатель от функции
  • Давайте будем гением компьютера.