В чем разница между size_t и int в C ++? - PullRequest
144 голосов
/ 02 февраля 2009

В нескольких примерах C ++ я вижу использование типа size_t, где я использовал бы простое int. В чем разница, и почему size_t должен быть лучше?

Ответы [ 5 ]

135 голосов
/ 02 февраля 2009

С дружелюбная Википедия :

Заголовочные файлы stdlib.h и stddef.h определяют тип данных с именем size_t , который используется для представления размера объекта. Библиотечные функции, принимающие размеры, ожидают, что они будут иметь тип size_t, а оператор sizeof оценивается как size_t.

Фактический тип size_t зависит от платформы; Распространенной ошибкой является допущение, что size_t - это то же самое, что и unsigned int, что может привести к ошибкам программирования, особенно из-за того, что 64-битные архитектуры становятся более распространенными.

Также проверьте Почему size_t имеет значение

28 голосов
/ 02 февраля 2009

size_t - это тип, используемый для представления размеров (как следует из его имен). Его платформа (и даже потенциально реализация) зависима и должна использоваться только для этой цели. Очевидно, представляющий размер, size_t без знака. Многие функции stdlib, включая malloc, sizeof и различные функции строковых операций, используют size_t в качестве типа данных.

Int подписывается по умолчанию, и хотя его размер также зависит от платформы, он будет фиксированным 32 бита на большинстве современных компьютеров (и хотя size_t составляет 64 бита в 64-битной архитектуре, int остается 32 битным в этих архитектурах ).

Подводя итог: используйте size_t для представления размера объекта и int (или long) в других случаях.

7 голосов
/ 02 февраля 2009

Это потому, что size_t может быть чем угодно, кроме int (может быть struct). Идея состоит в том, что он отделяет свою работу от базового типа.

6 голосов
/ 16 октября 2017

Тип size_t определяется как целочисленный тип без знака оператора sizeof. В реальном мире вы часто будете видеть int, определенный как 32 бита (для обратной совместимости), но size_t, определенный как 64 бита (так что вы можете объявить массивы и структуры размером более 4 ГиБ) на 64-битных платформах. Если 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, чей режим памяти 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, в зависимости от ситуации, и включить предупреждения компилятора о сравнении подписанных и неподписанных величин в случае пропуска любой. В любом случае вы всегда должны всегда проверять доступ к массиву на предмет переполнения в Си.

0 голосов
/ 24 мая 2016

Определение 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...