与堆数组相比,向量的边界检查有多严格?它究竟是如何检查边界的,以及如何与堆数组进行比较?
答案 0 :(得分:17)
如果您使用vector
函数,at()
将执行边界检查,例如:
std::vector<int> v(5);
v.at(3) = 10;
v.at(5) = 20; // throws an exception, std::out_of_range
但是,如果使用operator[]
,则没有边界检查。 (访问不存在的元素会导致未定义的行为。)
但应该注意的是,大多数实现都可以在所有迭代器上包含边界检查,这在答案here中有所讨论。默认情况下,VS2008及以下版本在Debug和Release中启用,VS2010仅在Debug中启用。 gcc要求您定义_GLIBCXX_DEBUG
以获取已检查的迭代器。
答案 1 :(得分:1)
这将是实现定义,vector contract不提供绑定检查保证。但是,你确实知道一件事,它将并不比堆数组更糟糕。
在我的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.
*/
答案 2 :(得分:1)
在典型的实现中,无论分配如何,都不会检查数组。 std::vector
需要对at()
进行边界检查。超出operator[]
的访问权限会给出未定义的行为,因此也可以对其进行边界检查,但这很不寻常。
然而,更重要的是,我建议一般使用算法,这些算法首先消除了关注点。当你执行类似:for (i=0; i<N; i++)
之类的操作时,N很容易成为错误的东西。当你使用algorithm(x.begin(), x.end(), ...);
时,你可以更容易地确定你的逻辑是否正确。