Как строгий границы проверяет векторы по сравнению с массивами "кучи"? Как точно это проверяет границы и как это соответствует тому, как массив "кучи" проверяется?
Вектор 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
для получения проверяемых итераторов.
Это будет определяться реализацией, векторный контракт не обеспечивает гарантий проверки границ. Но одно вы знаете наверняка, он будет не хуже массива кучи .
В моей реализации 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.
*/
В типичной реализации массивы не проверяются вообще, независимо от распределения. std::vector
требует проверки границ на at()
. Доступ за пределы границ с помощью operator[]
дает неопределенное поведение, поэтому можно сделать проверку границ и для него, но это довольно необычно.
Однако, что более важно, я бы посоветовал, как правило, использовать алгоритмы, которые в основном устраняют беспокойство в первую очередь. Когда вы делаете что-то вроде: for (i=0; i
algorithm(x.begin(), x.end(), ...);
, гораздо проще получить разумную степень уверенности в правильности вашей логики.