C++ 排序时更改排序顺序是否为未定义行为?

C++ 排序时更改排序顺序是否为未定义行为?,c++,multithreading,c++11,C++,Multithreading,C++11,想象一下以下场景: std::atomic<int> values[10]; std::size_t indices[10]; void sort() { std::iota(indices, indices+10, 0); std::sort(indices, indices+10, [&](size_t lhs, size_t rhs) { return values[lhs] < values[rhs]; }); }

想象一下以下场景:

std::atomic<int>  values[10];
std::size_t      indices[10];

void sort() {
    std::iota(indices, indices+10, 0);

    std::sort(indices, indices+10,
        [&](size_t lhs, size_t rhs) { return values[lhs] < values[rhs]; });
}
std::原子值[10];
标准:尺寸指数[10];
空排序(){
标准:物联网(指数,指数+10,0);
标准::排序(索引,索引+10,
[&](size_t lhs,size_t rhs){返回值[lhs]

运行排序()时,另一个线程正在更改值。这仅仅会导致之后索引没有正确排序,还是实际上是未定义的行为?

可能(见下文)是未定义的行为;在实践中,我已经看到了明显的崩溃(对于集装箱边界外的访问),即使只是不正确的(=不诱导总排序)比较器,并且
std::sort需要满足严格弱排序规则的分拣机。
(以英文解释)


如果同时更改内容,此顺序可能无法保持,从而导致未定义的行为。(可能导致分拣机无限循环、崩溃、之后索引未正确排序(如您所述)、索引正确排序、2个卫星或其他情况)

只是为了扮演魔鬼代言人,难道崩溃不是由标准库实现C++标准错误造成的吗?@贝诺:事实上,我正在查找标准中的一个引文。这可能不是明确的授权,但我相信,标准没有定义应该发生什么,因此,这使得其行为不明确。最近一期ish LWG将该措辞固定为“应”要求,我相当肯定库简介中有全局措辞违反此类要求。快速排序可能依赖于扫描期间存在比枢轴更小和更高的元素这一事实。如果你破坏了这个属性,算法可能会崩溃。我不确定。本能地,我会把这样的行为归入“疯狂的狗屎”一类。马丁·詹姆斯:在这个例子中,它看起来很耀眼,因为所有不相关的细节都被删除了。出现相同问题的一个更微妙的用例是按使用计数对共享的ptr向量进行排序。