STL排序不起作用

Dav*_*mes 0 c++ sorting stl

for (i = 0; i < t; i++)
{
  values.clear();

  scanf("%d %d %d", &values[0], &values[1], &values[2]);
  printf("%d %d %d\n", values[0], values[1], values[2]);
  sort(values.begin(), values.end());
  printf("%d %d %d\n", values[0], values[1], values[2]);

  printf("Case %d: %d\n", i + 1, values[1]);
}
Run Code Online (Sandbox Code Playgroud)

我有那个小片段.我输入"1200 1500 1800"它应该给我中间值 - 1500.但是,它输出1200,最小值.

我所做的是使用STL的sort()来对矢量进行排序,然后打印值[1],这是中间值.

但是,sort()似乎根本不起作用,之前和之后的打印矢量是相同的.

我用以下内容声明我的向量:

vector<int> values (3);
Run Code Online (Sandbox Code Playgroud)

我尝试用它vector<int> values;然后push_back(0)三次声明它.

我想知道为什么它不能以第一种方式工作.

And*_*owl 6

您的程序具有未定义的行为.

要修复它,只需删除此行:

values.clear();
Run Code Online (Sandbox Code Playgroud)

事实上,上述行的作用是擦除向量中的所有元素.然后,这一行:

scanf("%d %d %d", &values[0], &values[1], &values[2]);
                   ^^^^^^^^^   ^^^^^^^^^   ^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

将尝试访问不存在的元素.与operator []关联容器不同,operator []对于向量不会创建任何新元素.因此,表达式values[0],values[1]values[2]都是尝试访问不存在的元素.

根据C++ 11标准的表101:

表达:a[n]

返回类型:参考; const_reference为了恒定a

操作语义:*(a.begin() + n)

这意味着通过这样做:

values[0]
Run Code Online (Sandbox Code Playgroud)

你实际上是这样做的:

*(values.begin() + 0)
Run Code Online (Sandbox Code Playgroud)

values.begin()此处的调用将迭代器返回到数组中的第一个元素.由于向量中没有元素(第23.2.1/6节),因此调用values.begin()等同于对以下内容的调用values.end():

begin()返回一个迭代器,引用容器中的第一个元素.end()返回一个迭代器,它是容器的过去值.如果容器是空的,那么begin() == end();

因此,values[0]在您的情况下实际上相当于:

*(values.end() + 0)
Run Code Online (Sandbox Code Playgroud)

这反过来相当于:

*(values.end())
Run Code Online (Sandbox Code Playgroud)

换句话说,您正在取消引用指向容器中最后一个元素之外的位置的迭代器.这是未定义的行为,当然也适用于values[1]values[2].


Jos*_*eld 5

values.clear();
Run Code Online (Sandbox Code Playgroud)

这将清除,values以便它不再包含任何元素.尝试访问任何元素将导致未定义的行为,并且std::sort将简单地对空的数字序列进行排序.

a.clear()where a是序列容器的定义是:

销毁所有元素a.使引用元素的所有引用,指针和迭代器a无效并且可能使过去的迭代器无效.
post:a.empty()返回true