【问题标题】:Why does push_back into vector<vector<int>> causing seg fault?为什么 push_back 进入 vector<vector<int>> 会导致段错误?
【发布时间】:2019-09-14 04:09:08
【问题描述】:

想用邻接列表构造一个 Graph,但是当我向 vector&lt;vector&lt;int&gt;&gt; 添加元素时出现 seg-fault。 adj.size() 打印 5 告诉它已分配内存,为什么 addEdge() 方法中的 seg-fault?

 #define V 5

    struct Edge {
        int src, dst;
    };

    void addEdge(vector<vector<int>> &adj, int u, int v)
    {
        adj[u].push_back(v);
    }

    void constructGraph(vector<vector<int>> &adj, vector<Edge> &edges)
    {

        for(Edge e : edges)
        {
            addEdge(adj, e.src, e.dst);
        }
    }

    int main()
    {
       vector<vector<int>> adj(V);

       vector<Edge> edges =
        {
            { 0, 1 }, { 1, 2 }, { 2, 0 }, { 2, 1 },
            { 3, 2 }, { 4, 5 }, { 5, 4 }
        };

        constructGraph(adj, edges);

       return 0;
    }

【问题讨论】:

  • 5 超出了大小为 5 的向量的范围。我认为您的意思是 #define V 6?
  • 如果你使用过.at(),它会告诉你类似terminate called after throwing an instance of 'std::out_of_range'
  • @Andreas DM 是的,刚刚了解到使用 .at() 总是更安全,建议使用 [ ],我的 c 程序员必须努力学习。

标签: c++ vector segmentation-fault push-back


【解决方案1】:
void addEdge(vector<vector<int>> &adj, int u, int v)
{
    adj[u].push_back(v);
}

不正确。向量的operator[]() 假定提供的索引是有效的。如果u 无效,则行为未定义。

在您的代码中,传递的向量有五个元素,最后一条边在main()

vector<Edge> edges =
    {
        { 0, 1 }, { 1, 2 }, { 2, 0 }, { 2, 1 },
        { 3, 2 }, { 4, 5 }, { 5, 4 }               // note the last pair here
    };

将导致addEdge() 被调用,u 的值为5。就这样结束了。

虽然#define V 6 可以解决问题,但它不能保护addEdge() 不被传递u 的错误值。相反,我会实现addEdge(),这样它可以保护自己免受不良数据的影响,如下所示。

void addEdge(vector<vector<int>> &adj, int u, int v)
{
    if (u < 0) return;                   // handle negative u
    if (u >= adj.size()) adj.resize(u+1);  //   resize if needed
    adj[u].push_back(v);
} 

更好的方法是完全避免将提供的数据(例如main() 中的edges 中的数据)用作数组索引。

【讨论】:

    【解决方案2】:

    解决了。感谢您在此处提供的指导,阅读更多内容并了解到 C++ 语言内置了针对此类问题的保护。使用 .at() 方法可以保护程序员免受越界访问。

    void addEdge(vector<vector<int>> &adj, int u, int v)
    {
        adj.at(u).push_back(v);
    }
    

    如果你使用 adj.at(u) 而不是 adj[u],程序会优雅地退出

    terminate called after throwing an instance of 'std::out_of_range'
      what():  vector::_M_range_check: __n (which is 5) >= this->size() (which is 5)
    Aborted (core dumped)
    

    【讨论】:

      猜你喜欢
      • 2023-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-15
      • 1970-01-01
      相关资源
      最近更新 更多