Различаются ли размеры указателей в C? [duplicate]

Возможные дубликаты:
Может ли размер указателей меняться в зависимости от того, на что указывает?
Существуют ли платформы, на которых указатели на разные типы имеют разный размер?

Возможно ли, что размер указателя на float в c отличается от указателя на int? Попробовав, я получаю одинаковый результат для всех видов указателей.

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

int main()
{
    printf("sizeof(int*): %i\n", sizeof(int*));
    printf("sizeof(float*): %i\n", sizeof(float*));
    printf("sizeof(void*): %i\n", sizeof(void*));
    return 0;
}

Какие выходные данные здесь (OSX 10.6 64bit)

sizeof(int*): 8
sizeof(float*): 8
sizeof(void*): 8

Могу ли я предположить, что указатели разных типов имеют одинаковый размер (на одной арке, конечно)?

30
задан Community 23 May 2017 в 12:02
поделиться

11 ответов

Могу ли я предположить, что указатели разных типов имеют одинаковый размер (на одной арке, конечно)?

Для платформ с плоской моделью памяти (== все популярные / современные платформы) указатель размер будет таким же.

Для платформ с сегментированной моделью памяти для повышения эффективности часто используются специфичные для платформы типы указателей разного размера. (Например, указатели far в DOS, поскольку процессор 8086 использовал модель сегментированной памяти.) Но это специфично для платформы и нестандартно.

Вы, наверное, должны помнить, что в C ++ размер обычного указателя может отличаться от размера указателя на виртуальный метод. Указатели на виртуальные методы должны сохранять дополнительный бит информации, чтобы они не работали должным образом с полиморфизмом. Это, вероятно, единственное известное мне исключение, которое по-прежнему актуально (поскольку я сомневаюсь, что сегментированная модель памяти когда-либо вернется).

1
ответ дан 27 November 2019 в 23:47
поделиться

Указатели не всегда имеют одинаковый размер на одной арке.

Вы можете больше узнать о концепции «ближних», «дальних» и «огромных» указателей, просто в качестве примера случая, когда размеры указателей различаются ...

http://en.wikipedia.org / wiki / Intel_Memory_Model # Pointer_sizes

21
ответ дан 27 November 2019 в 23:47
поделиться

В былые времена, используя, например, В компиляторах Borland C на платформе DOS было всего (я думаю) 5 моделей памяти, которые можно было даже до некоторой степени смешивать. По сути, у вас был выбор между маленькими или большими указателями на данные, маленькими или большими указателями на код, а также «крошечной» моделью, в которой код и данные имели общее адресное пространство (если я правильно помню) 64 КБ.

Можно было указать «огромные» указатели в программе, которая в противном случае была бы построена по «крошечной» модели. Таким образом, в худшем случае можно было иметь указатели разного размера на один и тот же тип данных в одной программе!

Я думаю, что стандарт даже этого не запрещает, поэтому теоретически малоизвестный компилятор C мог бы сделать это даже сегодня. Но есть несомненные специалисты, которые смогут это подтвердить или исправить.

12
ответ дан 27 November 2019 в 23:47
поделиться

Я собирался написать ответ говоря, что C99 имеет различные требования к преобразованию указателей, которые более или менее гарантируют, что указатели на данные должны быть одинакового размера. Однако, внимательно прочитав их, я понял, что C99 специально разработан, чтобы позволить указателям иметь разный размер для разных типов.

Например, в архитектуре, где целые числа составляют 4 байта и должны быть выровнены по 4 байта, указатель int может быть на два бита меньше, чем указатель char или void. При условии, что актерский состав действительно сдвигается в обоих направлениях, вам подходит C99. В нем полезно говорится, что результат приведения указателя char к неправильно выровненному указателю int не определен.

См. Стандарт C99 . Раздел 6.3.2.3

4
ответ дан 27 November 2019 в 23:47
поделиться

Да. Это необычно, но это обязательно произойдет в системах, которые не имеют побайтной адресации. Например. 16-битная система с 64 Kword = 128KB памяти. В таких системах у вас все еще могут быть 16-битные указатели int. Но указателю char на 8-битный char потребуется дополнительный бит, чтобы указать старший / младший байт в слове, и, таким образом, у вас будут 17/32-битные указатели на char.

Это может звучать экзотично, но многие DSP тратят 99.x% времени на выполнение специализированного числового кода. Звуковой DSP может быть немного проще, если все, с чем он имеет дело, - это 16-битные данные, оставляя случайные 8-битные математические вычисления для эмуляции компилятору.

3
ответ дан 27 November 2019 в 23:47
поделиться

Да, размер указателя зависит от платформы. Точнее, размер указателя зависит от архитектуры целевого процессора и "разрядности", для которой вы компилируете.

Как правило, на 64-разрядной машине указатель обычно имеет размер 64 бита, на 32-разрядной машине - 32 бита. Однако есть и исключения.

Поскольку указатель - это просто адрес памяти, его размер всегда одинаков, независимо от того, что содержит память, на которую он указывает. Поэтому указатель на float, char или int имеет одинаковый размер.

3
ответ дан 27 November 2019 в 23:47
поделиться

Указатели всегда имеют одинаковый размер на одной и той же дуге, независимо от типа данных, на который они указывают. В противном случае такие вещи, как приведение типов указателей к разным типам, будут бесполезны и сломают множество вещей.

Многие распространенные методы кодирования зависят от приведения типов, например, между пустым указателем (или символом) к различным структурам, в зависимости от размера.

Возьмите даже стандартную функцию printf (), она должна иметь возможность принимать указатели на различные типы данных. Если бы указатели были разного размера, реализация printf могла бы стать очень запутанной.

0
ответ дан 27 November 2019 в 23:47
поделиться

Есть платформы, на которых указатели функций имеют другой размер, чем другие указатели.

Я никогда не видел большего разнообразия, чем это. Все другие указатели должны быть не более sizeof (void *), поскольку стандарт требует, чтобы их можно было преобразовать в void * без потери информации.

0
ответ дан 27 November 2019 в 23:47
поделиться

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

Следовательно, независимо от типа данных объекта, на который указывает указатель, размер указателя на конкретной машине будет одинаковым (поскольку пространство, необходимое для хранения адреса памяти, будет таким же).

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

-1
ответ дан 27 November 2019 в 23:47
поделиться

Насколько я понимаю, в стандарте C нет ничего, что могло бы гарантировать, что указатели на разные типы должны иметь одинаковый размер, поэтому теоретически int * и float * на одной платформе могут быть разные размеры без нарушения каких-либо правил.

Существует требование, чтобы char * и void * имели одинаковые требования к представлению и выравниванию, а также существуют различные другие аналогичные требования для разных подмножеств типов указателей, но нет ничего, что охватывало бы все.

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

6
ответ дан 27 November 2019 в 23:47
поделиться

Указатели на данные всегда должны быть совместимы с void * , поэтому, как правило, в настоящее время они будут реализованы как типы одинаковой ширины.

Это утверждение неверно для указателей на функции, они могут иметь разную ширину. По этой причине в C99 указатели функций приведения к void * являются неопределенным поведением.

9
ответ дан 27 November 2019 в 23:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: