Почему size_t лучше? - PullRequest
       33

Почему size_t лучше?

10 голосов
/ 21 октября 2011

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

size_t гарантированно сможет выразить максимальный размер любого объекта, включая любой массив

Я не очень понимаю, что это значит. Существует ли ограничение на объем памяти, который вы можете выделить за один раз, и size_t гарантированно будет достаточно большим для подсчета каждого байта в этом блоке памяти?

Дополнительный вопрос:
Что определяет, сколько памяти можно выделить?

Ответы [ 6 ]

9 голосов
/ 21 октября 2011

Скажем, самый большой объект, который может иметь ваш компилятор / платформа, это 4 ГБ. size_t тогда 32 бит. Теперь предположим, что вы перекомпилируете свою программу на 64-битной платформе, способной поддерживать объекты размером 2 ^ 43 - 1. size_t будет иметь длину не менее 43 бит (но обычно это будет 64 бит на данный момент). Дело в том, что вам нужно только перекомпилировать программу. Вам не нужно менять все свои int s на long (если int 32-битный и long 64-битный) или с int32_t на int64_t. (если вы спрашиваете себя, почему 43-разрядная версия, допустим, что 64-разрядная версия Windows Server 2008 R2 не поддерживает объекты размером 2 ^ 63 и объекты размером 2 ^ 62 ... Она поддерживает 8 ТБ адресуемой пробел ... Итак, 43 бит!)

Многие программы, написанные для Windows, считают указатель таким же большим, как DWORD (32-разрядное целое число без знака). Эти программы не могут быть перекомпилированы на 64 бит без переписывания больших кусков кода. Если бы они использовали DWORD_PTR (значение без знака, которое гарантированно должно быть настолько большим, насколько это необходимо для содержания указателя), у них не было бы этой проблемы.

«Точка» size_t аналогична. но отличается !

size_t не может содержать указатель !!
(DWORD_PTR в Microsoft Windows есть)

Это, как правило, незаконно:

void *p = ...
size_t p2 = (size_t)p;

Например, на старой платформе DOS максимальный размер объекта составлял 64 КБ, поэтому size_t должен был составлять 16 бит НО дальний указатель должен быть не менее 20 бит, потому что у 8086 было пространство памяти 1 мб (в конце дальний указатель был 16 + 16 бит, потому что память у 8086 была сегментирована)

6 голосов
/ 21 октября 2011

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

Это предпочтительнее, чем просто int, посколькуint и другие целочисленные типы могут быть меньше, чем те, которые могут быть проиндексированы.Например, int обычно имеет длину 32 бита, что недостаточно для индексации больших массивов на 64-битных машинах.(На самом деле это очень распространенная проблема при переносе программ на 64-битную версию.)

3 голосов
/ 21 октября 2011

Именно в этом причина.Максимальный размер любого объекта в данном языке программирования определяется комбинацией ОС, архитектуры ЦП и используемого компилятора / компоновщика.

size_t определяется как достаточно большой, чтобы содержать значение размерасамый большой возможный объект.

Это обычно означает, что size_t определен как typedef и соответствует наибольшему доступному типу int.Таким образом, в 32-битной среде это обычно 4 байта, а в 64-битной системе 8 байтов.

2 голосов
/ 21 октября 2011

size_t - это возвращение оператора sizeof (см. 7.17 c99), поэтому он должен описывать максимально возможный объект, который может представлять система.

2 голосов
/ 21 октября 2011

size_t определено для платформы, для которой вы компилируете.Следовательно, он может представлять максимум для этой платформы.

0 голосов
/ 21 октября 2011

Посмотрите на

http://en.wikipedia.org/wiki/Size_t

...