Действительно ли векторы более строги при проверке за пределы, чем массивы "кучи"?

Как строгий границы проверяет векторы по сравнению с массивами "кучи"? Как точно это проверяет границы и как это соответствует тому, как массив "кучи" проверяется?

7
задан Cascabel 16 June 2010 в 20:34
поделиться

3 ответа

Вектор vector будет выполнять проверку границ, если вы используете функцию at(), например:

std::vector<int> v(5);
v.at(3) = 10; 
v.at(5) = 20; // throws an exception, std::out_of_range

Однако, если вы используете operator[], проверка границ не выполняется. (А обращение к несуществующим элементам приводит к неопределенному поведению.)

Следует отметить, однако, что в большинстве реализаций есть возможность включить проверку границ для всех итераторов, что обсуждается в ответах здесь. По умолчанию в VS2008 и ниже она включена в Debug и Release, в VS2010 - только в Debug. gcc требует, чтобы вы определили _GLIBCXX_DEBUG для получения проверяемых итераторов.

18
ответ дан 6 December 2019 в 09:18
поделиться

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

В моей реализации sgi:

  • vector :: operator [] не проверяется
  • vector :: at () привязан проверяется

Из определения файла заголовка operator [] :

  /**
   *  @brief  Subscript access to the data contained in the %vector.
   *  @param n The index of the element for which data should be
   *  accessed.
   *  @return  Read-only (constant) reference to data.
   *
   *  This operator allows for easy, array-style, data access.
   *  Note that data access with this operator is unchecked and
   *  out_of_range lookups are not defined. (For checked lookups
   *  see at().)
   */

И для vector :: at () :

  /**
   *  @brief  Provides access to the data contained in the %vector.
   *  @param n The index of the element for which data should be
   *  accessed.
   *  @return  Read/write reference to data.
   *  @throw  std::out_of_range  If @a n is an invalid index.
   *
   *  This function provides for safer data access.  The parameter
   *  is first checked that it is in the range of the vector.  The
   *  function throws out_of_range if the check fails.
   */
1
ответ дан 6 December 2019 в 09:18
поделиться

В типичной реализации массивы не проверяются вообще, независимо от распределения. std::vector требует проверки границ на at(). Доступ за пределы границ с помощью operator[] дает неопределенное поведение, поэтому можно сделать проверку границ и для него, но это довольно необычно.

Однако, что более важно, я бы посоветовал, как правило, использовать алгоритмы, которые в основном устраняют беспокойство в первую очередь. Когда вы делаете что-то вроде: for (i=0; i, довольно легко сделать так, чтобы N было неправильным. Когда вы используете algorithm(x.begin(), x.end(), ...);, гораздо проще получить разумную степень уверенности в правильности вашей логики.

1
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: