Почему size_t лучше?
Название на самом деле немного вводит в заблуждение, но я хотел бы держать его коротким. Я читал о том, почему я должен использовать size_t, и я часто нашел такие утверждения:
size_t
гарантированно сможет выразить максимальный размер любого объекта, включая любой массив
Я действительно не понимаю, что это значит. Есть ли какая-то подсказка о том, сколько памяти вы можете выделить сразу, и size_t гарантированно будет достаточно большим, чтобы подсчитывать каждый байт в этом блоке памяти?
Последующий вопрос:
Что определяет, сколько памяти может быть выделено?
Ответы
Ответ 1
Скажем, самый большой объект, который может иметь ваш компилятор/платформа, составляет 4 ГБ. size_t
, тогда 32 бит. Теперь позвольте сказать, что вы перекомпилируете свою программу на 64-битной платформе, способной поддерживать объекты размером 2 ^ 43 - 1. size_t
будет как минимум 43 бит (но обычно это будет 64 бит на данный момент). Дело в том, что вам нужно только перекомпилировать программу. Вам не нужно менять все ваши int
на long
(если int
- 32 бит, а long
- 64 бит) или от int32_t
до int64_t
.
(если вы спрашиваете себя, почему 43 бит, скажем, что Windows Server 2008 R2 64bit не поддерживает объекты размером 2 ^ 63 или объекты размером 2 ^ 62... Он поддерживает 8 TB адресного пространства... Так что 43 бит!)
Многие программы, написанные для Windows, считали, что указатель будет таким же большим, как DWORD
(32-разрядное целое число без знака). Эти программы не могут быть перекомпилированы на 64-битной основе без перезаписи больших кодов кода. Если бы они использовали DWORD_PTR
(значение без знака, гарантированное быть настолько большим, сколько необходимо, чтобы содержать указатель), у них не было бы этой проблемы.
Точка size_t
"аналогична. , но разные!
size_t
не может содержать указатель!
(DWORD_PTR
для Microsoft Windows)
Это, в общем, незаконно:
void *p = ...
size_t p2 = (size_t)p;
Например, на старой DOS-платформе максимальный размер объекта был 64k, поэтому size_t
должен был быть 16 бит НО, а указатель должен был быть как минимум 20 бит, потому что у 8086 было пространство памяти 1 мб (в итоге дальний указатель был 16 + 16 бит, потому что память 8086 была сегментирована)
Ответ 2
В основном это означает, что size_t
гарантированно будет достаточно большим, чтобы индексировать любой массив и получать размер любого типа данных.
Предпочтительно использовать только int
, потому что размер int
и других целочисленных типов может быть меньше, чем можно индексировать. Например, int
обычно имеет длину 32 бит, что недостаточно для индексации больших массивов на 64-разрядных машинах. (На самом деле это очень распространенная проблема при переносе программ на 64-разрядные.)
Ответ 3
Именно по этой причине.
Максимальный размер любого объекта в данном языке программирования определяется комбинацией ОС, архитектуры ЦП и используемого компилятора/компоновщика.
size_t определяется как достаточно большой, чтобы удерживать значение размера максимально возможного объекта.
Это обычно означает, что size_t typedef'ed будет таким же, как и самый большой доступный тип int.
Таким образом, в 32-битной среде обычно будет 4 байта, а в 64-битной системе - 8 байтов.
Ответ 4
size_t
определяется для платформы, для которой вы компилируете. Следовательно, он может представлять максимум для этой платформы.
Ответ 5
size_t - это возврат оператора sizeof (см. 7.17 c99), поэтому он должен описывать самый большой возможный объект, который может представлять система.
Ответ 6
Посмотрите
http://en.wikipedia.org/wiki/Size_t