Должен ли я всегда использовать size_t при индексации массивов? - PullRequest
11 голосов
/ 10 апреля 2019

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

Вопрос не в том, когда мне следует использовать size_t. Я просто хочу знать, если, например, программа имеет 2 ГБ доступной памяти (все эти поля могут быть проиндексированы с помощью int32), но эта память (виртуальная память) назначается "полям" 14 ГБ - 16 ГБ компьютера RAM.

Всегда ли произойдет сбой при индексации памяти, если в этом случае я буду использовать int32 вместо size_t (или unsigned long int)?

Возможно, вопрос скорее в виртуальной памяти, чем в указателях.

Спасибо, что ответили.

Ответы [ 2 ]

8 голосов
/ 10 апреля 2019

size_t - это целое число без знака, которое может содержать размер самого большого объекта, который вы можете выделить. Это полезно для индексации, потому что это означает, что он может индексировать в самый большой массив, который вы можете выделить.

Это не означает, что это требуется или даже обязательно рекомендуется для индексации. Вы можете использовать любой целочисленный тип, достаточный для индексации массива. int_fast32_t может быть быстрее, uint_least16_t может быть меньше в структуре и так далее. Знайте свои данные, и вы сможете сделать правильный выбор.

Виртуальная память выходит за рамки C или C ++. С их точки зрения, вы просто индексируете память, и ваша платформа должна заставить ее работать. На практике ваше приложение использует только виртуальные адреса; ваш ЦП / ОС переводит виртуальный адрес в физический адрес за кулисами. Вам не о чем беспокоиться.

0 голосов
/ 12 апреля 2019

Чтобы избежать программных сбоев, программист должен всегда использовать индексный тип, по крайней мере такой же большой, как тип, возвращаемый методом 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 в случае массивов, сжатых в памяти (если метод массива size() возвращает aint)
  • aint в случае массивов, охватывающих несколько машин (если массив size()метод возвращает aint)
  • Другие языки, кроме C ++:
    • int в случае java.util.Collection и его подклассов

InСводка: безопасный тип индекса - это тип, возвращаемый методом size().

Примечание: если метод size() возвращает беззнаковое size_t, тогда подписанные int и ssize_t aren 'т безопасных типов индексов.В случае gcc и clang флаги компилятора -Wsign-compare (включенные -Wall) и -Wconversion могут использоваться для предотвращения большинства этих случаев.

...