Відповіді:
Файли заголовків stdlib.h та stddef.h визначають тип даних під назвою size_t, який використовується для представлення розміру об'єкта. Функції бібліотеки, які приймають розміри, очікують, що вони будуть типу size_t, а оператор sizeof оцінює до size_t.
Фактичний тип size_t залежить від платформи; Поширена помилка полягає в тому, що вважати, що size_t є тим самим, що і непідписаний int, що може призвести до помилок програмування, особливо, коли 64-бітні архітектури стають більш поширеними.
Також перевірте, чому розмір має значення
/usr/include/stdlib.h
отримує визначення, /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.h
а в ньому - за замовчуванням, long unsigned int
якщо інший файл заголовка не говорить інше.
size_t - тип, який використовується для представлення розмірів (як випливає з його назв). Його платформа (і навіть потенційно реалізація) залежить, і її слід використовувати лише для цієї мети. Очевидно, що представляє розмір, розмір_t не підписаний. Багато функцій stdlib, включаючи malloc, sizeof та різні функції рядкових операцій, використовують size_t як тип даних.
Int підписаний за замовчуванням, і хоча його розмір також залежить від платформи, він буде фіксованим 32-бітним на більшості сучасних машин (і хоча size_t становить 64 біти в 64-бітній архітектурі, int залишається 32-бітним в цих архітектурах).
Підводячи підсумок: використовуйте size_t для представлення розміру об'єкта, а int (або довгий) в інших випадках.
size_t
Тип визначається як беззнаковое інтегрального типу sizeof
оператора. У реальному світі ви часто будете int
визначатись як 32 біти (для зворотної сумісності), але size_t
визначені як 64 біти (тому ви можете оголошувати масиви та структури розміром більше 4 Гб) на 64-бітних платформах. Якщо a long 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, у режимі якого величезна пам'ять було 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 (можливо, структура). Ідея полягає в тому, що вона відокремлює роботу від основного типу.
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
максимальну кількість байтів, на які може вказувати вказівник.
Цей тип декларується наступним чином:
typedef ULONG_PTR SIZE_T;
A ULONG_PTR
- це ненаписаний довгий тип, який використовується для точності вказівника. Він використовується під час наведення покажчика на довгий тип для виконання арифметики вказівника.
Цей тип декларується наступним чином:
typedef unsigned __int3264 ULONG_PTR;
SIZE_T
не size_t
те, про що запитувала ОП.
SIZE_T
абсолютно відрізняється від size_t
. Ви не можете оголосити змінну типу SIZE_T
.