Должен ли я всегда использовать size_t при индексации массивов?
Нужно ли всегда использовать size_t
при индексировании массива, даже если массив недостаточно велик, чтобы превышать размер целого?
Это не вопрос о том, когда мне следует использовать size_t
. Я просто хочу знать, если, например, программа имеет 2 ГБ доступной памяти (все эти поля могут быть проиндексированы с помощью int32), но эта память (виртуальная память) назначается "полям" 14 ГБ - 16 ГБ компьютера RAM.
Будет ли всегда происходить сбой при индексации памяти, если в этом случае я буду использовать int32
вместо size_t
(или unsigned long int
)?
Может быть, вопрос больше о виртуальной памяти, чем об указателях.
Ответы
Ответ 1
size_t
- это целое число без знака, которое может содержать размер самого большого объекта, который вы можете выделить. Это полезно для индексации, потому что это означает, что он может индексировать в самый большой массив, который вы можете выделить.
Это не означает, что это требуется или даже обязательно рекомендуется для индексации. Вы можете использовать любой целочисленный тип, достаточный для индексации массива. int_fast32_t
может быть быстрее, uint_least16_t
может быть меньше в структуре и так далее. Знайте свои данные, и вы сможете сделать хороший выбор.
Виртуальная память выходит за рамки C или C++. С их точки зрения, вы просто индексируете в память и до своей платформы, чтобы она работала. На практике ваше приложение использует только виртуальные адреса; ваш ЦП/ОС переводит виртуальный адрес в физический адрес за кулисами. Вам не о чем беспокоиться.
Ответ 2
Использование size_t
для индексации массива связано с типом данных или максимальным адресуемым размером, превышающим его.
size_t
- это unsigned int
, потому что индекс массива не может быть отрицательным, если использовать size_t в качестве переменной цикла, чтобы ваша программа не сталкивалась с отрицательным
Ответ 3
Чтобы избежать сбоев программы, программист должен всегда использовать индексный тип, по крайней мере такой же большой, как тип, возвращаемый методом size()
. Это гарантирует, что индекс никогда не переполняет любой возможный размер массива. Реализация массива обычно гарантирует, что его размер во время выполнения никогда не переполняет тип, возвращаемый методом size()
. Это означает, что тип индекса должен быть:
-
size_t
в случае char[N]
, uint8_t[N]
, int[N]
и т.д. -
size_t
в случае std::vector
и std::list
-
int
в случае QList
и QVector
- произвольное целочисленное значение точности (aint) в случае битовых массивов (если метод bitarray
size()
возвращает aint) - aint в случае массивов, сжатых в памяти (если метод array
size()
возвращает aint) - aint в случае массивов, охватывающих несколько машин (если метод array
size()
возвращает aint) - Другие языки, кроме C++:
-
int
в случае java.util.Collection
и его подклассов
Итак, безопасный тип индекса - это тип, возвращаемый методом size()
.
Примечание. Если метод size()
возвращает unsigned size_t
, то подписанные int
и ssize_t
не являются безопасными типами индекса. В случае gcc и clang флаги компилятора -Wsign-compare
(включенные -Wall
) и -Wconversion
могут использоваться для предотвращения большинства этих случаев.