对空向量进行排序

std::sort on empty vector

本文关键字:排序 向量      更新时间:2023-10-16

如果std::sort得到一个空范围,它应该正确工作吗?

我得到一个分段错误(gcc 4.8.3):

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

标准说明对于空向量begin()end()返回相同的值。所以我期望sort在上面的情况下什么都不做,因为它应该得到一个空范围:begin()+1应该大于end()

对于这个空范围sort:

没有问题
std::sort( f.begin(), f.end() );

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更可取。

对输入迭代器进行递增操作有一个先决条件,即迭代器必须是可解引用的。对于空向量,v.begin()是不可解引用的,因此尝试执行v.begin() + 1(它又以增量方式定义)是未定义的行为。

此外,std::sort(begin, end)要求[begin, end)是有效范围,并且标准规定(§24.2.1 [iterator.requirements.general]/p7)

Range [i,j)当且仅当ji可达时有效。将标准库中的函数应用于无效范围的结果是未定义的。

对于大多数随机访问迭代器(唯一定义了<>的迭代器类型),如果a > ba不能从b访问,因此[a, b) 表示空范围——它根本不表示有效范围。

f.begin()+1越界,这就是分割错误的原因。

使用f.begin()作为数组的开头。这样使用起来就很安全了