尝试取消引用迭代器时出现段错误

hsb*_*hsb 1 c++ iterator std

我正在尝试从向量中获取minmax元素。下面是我的代码的过度简化的片段:

std::vector<int> vec;
for (int i = 1; i < 10; i++) {
  vec.push_back(i);
}
auto minmax = std::minmax(vec.begin(), vec.end());
int min_value = *minmax.first;
Run Code Online (Sandbox Code Playgroud)

当我尝试在最后一条语句中取消引用迭代器时,出现段错误。我不明白为什么。

lub*_*bgr 5

这里的问题并不那么明显。正如其他人已经建议的那样,您正在使用错误的算法,或者以错误的方式使用了算法。当您要使用迭代器并传递范围时,请使用以下命令:

auto minmax = std::minmax_element(vec.cbegin(), vec.cend());
int min_value = *minmax.first;
Run Code Online (Sandbox Code Playgroud)

如果你不是想用std::minmax,你需要或者通类型的两个参数,你想比较,或者std::initializer_list

auto minmax1 = std::minmax_element(42, 43);
auto minmax2 = std::minmax_element({42, 43, 50, 49, 40});

int min_value = minmax1.first;
Run Code Online (Sandbox Code Playgroud)

在第二个示例中,返回的不是迭代器,而是const-限定的引用或值(当传递了初始化程序列表时)。

你为什么犯那个错误?事实证明,传递迭代器以进行std::minmax愉快的编译是因为它std::minmax是一个函数模板,可以比较您提供的任何类型。在这种情况下,vec.begin()vec.end()是随机访问迭代器,可以通过比较它们operator <。序列开始处的随机访问迭代器将始终与指向末尾的迭代器进行比较,因此,您获得的最小值实际上是对和的一对const引用vec.begin()vec.end()因为vec.begin() < vec.end()(未考虑中间值),但是在函数调用之后不再存在,使用它们(例如,取消引用它们)是UB(附加说明:理论上,您可以通过以下方法解决此问题:int min_value = *std::minmax(vec.begin(), vec.end()).first;,它在不悬空时取消对返回的Interator的引用,但这只是修复UB部分,而不是您想要的,即它仍然比较两个迭代器,而不是范围内的元素)。

请注意,当您尝试使用a std::list<int>而不是a 编译此示例时std::vector,它将不会编译,因为std::list迭代器不是随机访问的,并且不能通过进行比较operator <

有时,随机访问的功能可能会给您带来麻烦:)