Почему 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), поэтому он должен описывать самый большой возможный объект, который может представлять система.