std ::在空向量上排序

时间:2014-06-18 16:28:21

标签: c++ sorting c++11 vector

如果std::sort获得空的范围,它是否应该正常工作?

我为此代码得到了分段错误(gcc 4.8.3):

std::vector<float> f;
std::sort( f.begin() + 1, f.end() );

标准说,对于空向量begin()end(),返回相同的值。因此,我希望sort在上述情况下不执行任何操作,因为它应该为空范围:begin()+1应该大于end()

这个空范围排序没有问题:

std::sort( f.begin(), f.end() );

3 个答案:

答案 0 :(得分:4)

std::sort期望[begin, end)成为有效范围,这样如果您继续增加begin,您最终会到达end。在您的情况下,begin()+1已超过end(),因此std::sort无法知道它正在超出范围的末尾。

std::sort接受迭代器,而不是指针。正因为如此,它无法运行begin < end检查:如果您为两个迭代器传递rbegin()rend(),则会失败。

如果要对排除初始元素的std::vector的一部分进行排序,则需要确保容器不为空。否则,begin()+1将产生无效的迭代器。

注意:虽然从技术角度来说,当您在空容器上执行begin()+1时会发生未定义的行为,但您的案例中的崩溃几乎肯定来自std::sort内的解除引用。另请注意,如果您使用符合C ++ 11的编译器,则使用std::next(v.begin(), 1)优先于v.begin() + 1

答案 1 :(得分:2)

输入迭代器的增量有一个前提条件,迭代器必须可解除引用。使用空向量时,v.begin()不可解除引用,因此尝试执行v.begin() + 1(根据增量定义)是未定义的行为。

此外,std::sort(begin, end)要求[begin, end)为有效范围,标准表示(§24.2.1[iterator.requirements.general] / p7)

  当且仅当[i,j)可以从j访问时,

范围i才有效。将函数库中的函数应用于无效范围的结果是未定义的。

对于大多数随机访问迭代器(已定义<>的唯一迭代器类型),如果a > b无法从a到达b }},所以[a, b) 表示空范围 - 它根本不表示有效范围。

答案 2 :(得分:1)

f.begin()+1超出范围,这就是分段错误的原因。

使用f.begin()作为数组的开头。这样可以安全使用。