Должен ли я всегда использовать 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 могут использоваться для предотвращения большинства этих случаев.