c++ - 尝试取消引用迭代器时出现段错误
问题描述
我正在尝试从向量中获取 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;
当我尝试在最后一条语句中取消引用迭代器时,出现段错误。我不明白为什么。
解决方案
这里的问题并不像它可能的那样明显。正如其他人已经建议的那样,您使用了错误的算法,或者以错误的方式使用了算法。当你想使用迭代器并传入一个范围时,使用这个:
auto minmax = std::minmax_element(vec.cbegin(), vec.cend());
int min_value = *minmax.first;
如果您想使用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;
在第二个示例中,返回的不是迭代器,而是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;
,它在返回的迭代器没有悬空时取消引用,但这只是修复了 UB 部分,而不是你想要的,即它仍然比较两个迭代器,而不是范围内的元素)。
请注意,当您尝试使用 astd::list<int>
而不是 a来编译此示例时std::vector
,它将无法编译,因为std::list
迭代器不是随机访问且无法通过 比较operator <
。
有时,随机访问的力量似乎会给你带来麻烦:)
推荐阅读
- react-native - 抽屉导航器在注销后保留状态。如何清除它的状态
- android - Gridview Flutter 中的 BoxDecoration 溢出
- java - 如何显示桌面通知?
- spring-boot - 在 Spring Boot 中描述 String swagger 响应模式
- php - 将文件拆分为多个字节范围
- javascript - 为什么未显示 vuetify 日历中的事件?
- javascript - 创建一个将更新状态的 axios 调用,然后执行另一个
- java - 如何在两个日期之间制作 TableRowShorter
- kotlin - Kotlin `object` 初始化顺序导致意外的空实例
- android - 有哪些安全/安全的在线安卓模拟器可用?