Заголовочные файлы stdlib.h и stddef.h определяют тип данных с именем size_t, который используется для представления размера объекта. Библиотечные функции, принимающие размеры, ожидают, что они будут иметь тип size_t, а оператор sizeof оценивается как size_t.
Фактический тип size_t зависит от платформы; Распространенной ошибкой является допущение, что size_t - это то же самое, что и unsigned int, что может привести к ошибкам в программировании, особенно когда 64-битные архитектуры становятся более распространенными.
@ NDEthos Это зависит! По этому здесь Linux /usr/include/stdlib.hполучает определение /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.hи в нем по умолчанию используется значение, long unsigned intесли другой заголовочный файл не говорит иначе.
Дэвид Тонхофер
1
Я подтверждаю, что size_t для интонации опасен . Это может быть не по теме, но как написать патч в одиночку, чтобы исправить ошибки такого рода, когда они происходят тысячи раз в ядре Linux?
user2284570
36
size_t - это тип, используемый для представления размеров (как следует из его имен). Его платформа (и даже потенциально реализация) зависима и должна использоваться только для этой цели. Очевидно, представляющий размер, size_t без знака. Многие функции stdlib, включая malloc, sizeof и различные функции строковых операций, используют size_t в качестве типа данных.
Int подписывается по умолчанию, и хотя его размер также зависит от платформы, он будет фиксированным 32 бита на большинстве современных компьютеров (и хотя size_t равен 64 битам в 64-битной архитектуре, int остается 32 битным в этих архитектурах).
Подводя итог: используйте size_t для представления размера объекта и int (или long) в других случаях.
size_tТип определяется как беззнаковое интегрального типа sizeofоператора. В реальном мире вы часто будете видеть int32 size_t-битные (для обратной совместимости), но 64-битные (чтобы вы могли объявлять массивы и структуры размером более 4 ГиБ) на 64-битных платформах. Если a long intтакже 64-битный, это называется соглашением LP64; Если long int32- long long intбитный, а указатели 64-битные, это LLP64. Вы также можете получить обратную, программу, которая использует 64-битные инструкции для скорости, но 32-битные указатели для экономии памяти. Также intподписано и size_tне подписано.
Исторически было много других платформ, где адреса были шире или короче, чем собственный размер int. Фактически, в 70-х и в начале 80-х это было более распространенным, чем нет: все популярные 8-битные микрокомпьютеры имели 8-битные регистры и 16-битные адреса, а переход между 16 и 32-битными также породил множество машин, которые адреса были шире, чем их регистры. Иногда я все еще вижу здесь вопросы о Borland Turbo C для MS-DOS, чей режим памяти Huge содержал 20-битные адреса, хранящиеся в 32-битном режиме на 16-битном процессоре (но который мог поддерживать 32-битный набор инструкций 80386); Motorola 68000 имел 16-битный ALU с 32-битными регистрами и адресами; были мэйнфреймы IBM с 15-битными, 24-битными или 31-битными адресами. Вы также все еще видите различные размеры ALU и адресной шины во встроенных системах.
В любое время intменьше чем size_t, и вы пытаетесь сохранить размер или смещение очень большого файла или объекта в unsigned int, есть вероятность, что он может переполниться и вызвать ошибку. С int, есть также возможность получить отрицательное число. Если intили unsigned intбольше, программа будет работать правильно, но тратить память.
Как правило, вы должны использовать правильный тип для этой цели, если вы хотите переносимости. Многие люди порекомендуют вам использовать математику со знаком вместо без знака (чтобы избежать неприятных, тонких ошибок, таких как 1U < -3). Для этой цели стандартная библиотека определяет ptrdiff_tв <stddef.h>качестве типа со знаком результат вычитания указателя из другого.
Тем не менее, обходным путем может быть проверка границ всех адресов и смещений по отношению к INT_MAXи / 0или по INT_MINмере необходимости и включение предупреждений компилятора о сравнении подписанных и неподписанных величин в случае, если вы пропустите какие-либо из них. Вы должны всегда, всегда, всегда проверять доступ к массиву для переполнения в C в любом случае.
Я думаю, что size_t на самом деле гарантированно будет псевдонимом для целого числа без знака, поэтому он не может быть структурой. У меня нет справки, чтобы поддержать это прямо сейчас, хотя.
расслабиться
9
@unwind: C99: TC3, 7.17 §2
Кристоф,
1
@danio Почему это так? Вы можете объяснить?
Стервятник Руппелла
2
Я бы не стал ссылаться на cplusplus, если бы я был тобой! Если вы не можете процитировать главу, стих, абзац и строку, тогда все это просто слухи! :-)
graham.reeds
1
size_tуказывается как целое число без знака . C11 §6.5.3.4 5 «Значение результата обоих операторов ( sizeof_Alignof) определяется реализацией, а его тип (целочисленный тип без знака) равен size_t« ».
SIZE_T это ULONG_PTR представляющим максимальным числом байт , к которому указатель может указывать.
Этот тип объявлен следующим образом:
typedef ULONG_PTR SIZE_T;
A ULONG_PTR- это длинный тип без знака, используемый для точности указателя. Он используется при приведении указателя к длинному типу для выполнения арифметики указателя.
Ответы:
Из дружественной Википедии :
Также проверьте, почему size_t имеет значение
источник
/usr/include/stdlib.h
получает определение/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.h
и в нем по умолчанию используется значение,long unsigned int
если другой заголовочный файл не говорит иначе.size_t - это тип, используемый для представления размеров (как следует из его имен). Его платформа (и даже потенциально реализация) зависима и должна использоваться только для этой цели. Очевидно, представляющий размер, size_t без знака. Многие функции stdlib, включая malloc, sizeof и различные функции строковых операций, используют size_t в качестве типа данных.
Int подписывается по умолчанию, и хотя его размер также зависит от платформы, он будет фиксированным 32 бита на большинстве современных компьютеров (и хотя size_t равен 64 битам в 64-битной архитектуре, int остается 32 битным в этих архитектурах).
Подводя итог: используйте size_t для представления размера объекта и int (или long) в других случаях.
источник
size_t
Тип определяется как беззнаковое интегрального типаsizeof
оператора. В реальном мире вы часто будете видетьint
32size_t
-битные (для обратной совместимости), но 64-битные (чтобы вы могли объявлять массивы и структуры размером более 4 ГиБ) на 64-битных платформах. Если along int
также 64-битный, это называется соглашением LP64; Еслиlong int
32-long long int
битный, а указатели 64-битные, это LLP64. Вы также можете получить обратную, программу, которая использует 64-битные инструкции для скорости, но 32-битные указатели для экономии памяти. Такжеint
подписано иsize_t
не подписано.Исторически было много других платформ, где адреса были шире или короче, чем собственный размер
int
. Фактически, в 70-х и в начале 80-х это было более распространенным, чем нет: все популярные 8-битные микрокомпьютеры имели 8-битные регистры и 16-битные адреса, а переход между 16 и 32-битными также породил множество машин, которые адреса были шире, чем их регистры. Иногда я все еще вижу здесь вопросы о Borland Turbo C для MS-DOS, чей режим памяти Huge содержал 20-битные адреса, хранящиеся в 32-битном режиме на 16-битном процессоре (но который мог поддерживать 32-битный набор инструкций 80386); Motorola 68000 имел 16-битный ALU с 32-битными регистрами и адресами; были мэйнфреймы IBM с 15-битными, 24-битными или 31-битными адресами. Вы также все еще видите различные размеры ALU и адресной шины во встроенных системах.В любое время
int
меньше чемsize_t
, и вы пытаетесь сохранить размер или смещение очень большого файла или объекта вunsigned int
, есть вероятность, что он может переполниться и вызвать ошибку. Сint
, есть также возможность получить отрицательное число. Еслиint
илиunsigned int
больше, программа будет работать правильно, но тратить память.Как правило, вы должны использовать правильный тип для этой цели, если вы хотите переносимости. Многие люди порекомендуют вам использовать математику со знаком вместо без знака (чтобы избежать неприятных, тонких ошибок, таких как
1U < -3
). Для этой цели стандартная библиотека определяетptrdiff_t
в<stddef.h>
качестве типа со знаком результат вычитания указателя из другого.Тем не менее, обходным путем может быть проверка границ всех адресов и смещений по отношению к
INT_MAX
и /0
или поINT_MIN
мере необходимости и включение предупреждений компилятора о сравнении подписанных и неподписанных величин в случае, если вы пропустите какие-либо из них. Вы должны всегда, всегда, всегда проверять доступ к массиву для переполнения в C в любом случае.источник
Это потому, что size_t может быть чем угодно, кроме int (может быть struct). Идея состоит в том, что он отделяет свою работу от базового типа.
источник
size_t
указывается как целое число без знака . C11 §6.5.3.4 5 «Значение результата обоих операторов (sizeof
_Alignof
) определяется реализацией, а его тип (целочисленный тип без знака) равенsize_t
« ».Определение
SIZE_T
можно найти по адресу: https://msdn.microsoft.com/en-us/library/cc441980.aspx и https://msdn.microsoft.com/en-us/library/cc230394.aspx.Вставьте сюда необходимую информацию:
SIZE_T
этоULONG_PTR
представляющим максимальным числом байт , к которому указатель может указывать.Этот тип объявлен следующим образом:
A
ULONG_PTR
- это длинный тип без знака, используемый для точности указателя. Он используется при приведении указателя к длинному типу для выполнения арифметики указателя.Этот тип объявлен следующим образом:
источник
SIZE_T
не тоsize_t
, о чем спрашивал ОП.SIZE_T
полностью отличается отsize_t
. Вы не можете объявить переменную типаSIZE_T
.