【问题标题】:"Out of bound iterator" with an empty set带有空集的“越界迭代器”
【发布时间】:2018-11-27 12:14:11
【问题描述】:

我在这段代码中遇到了分段错误:

#include <iostream>
#include <set>

int main() {
    std::set<int> st;
    auto rf = --st.end();
    std::cout << "Size of the set is: " << (int) st.size() << std::endl;

    if ( (int) st.size() > 0) { // size of st is zero here
        int foo = (*rf);  // rf is out bound
        std::cout << "foo: " << foo << std::endl;
    }
}

由于st 为空,因此if 条件永远不会为真,无论rf 是否超出范围。如果我注释掉if 块,那么程序运行良好。

我也用std::vector 尝试过,它运行良好。

为什么会出现分段错误?为什么'always false if condition with invalid statement'会影响代码的运行?

编译:

g++ -Wall -Wextra -Wshadow -Wfloat-equal -pedantic -std=c++17 -Wconversion -lm test.cpp

【问题讨论】:

  • 您不能为空容器执行--sr.end();。我是否取消引用迭代器并不重要。您有未定义的行为,任何更改都可以在没有解释的情况下将其关闭。
  • 使用调试器捕捉崩溃。它不会发生在你认为会发生的地方。
  • 如果std::set 为空,则begin == end 为真,这意味着递减end 没有任何意义,并且有未定义行为的味道。
  • 伙计们,不要在评论中回答;)
  • 顺便说一句,如果你想要指向最终元素的东西,并且除了BidirectionalIterator之外不关心它的类型,你可以使用st.rbegin()

标签: c++ iterator segmentation-fault set c++17


【解决方案1】:

这是未定义的行为:

std::set<int> st;
auto rf = --st.end();

由于 st 为空,st.begin() == st.end() 并递减这两个(和相同的)迭代器中的任何一个都是不正确的。

我也尝试过使用矢量并且运行良好。

这是 UB 最有害的后果之一:它可能看起来没问题。不是。

【讨论】:

    猜你喜欢
    • 2016-10-19
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2012-07-07
    • 2021-05-05
    相关资源
    最近更新 更多