You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++邻接表实现中向pair型vector添加元素触发SIGSEGV段错误

问题分析

你遇到的段错误由两个核心问题共同导致:

  • 邻接表访问逻辑完全错误
    你定义的edges是标准邻接表结构:内层std::vector<std::pair<uint32_t, float>>存储单个起点的所有出边集合,每个元素是(目标节点编号, 边权重),你直接用目标节点编号to作为内层vector的下标访问,本质是把邻接表当成了邻接矩阵使用。只要to的数值大于内层vector的长度,就会触发越界访问,这是段错误的核心诱因。
  • 未初始化edges的外层容量
    外层edges vector的长度需要和图的总节点数保持一致,你类中已经定义了纯虚函数get_num_nodes()获取总节点数,但你没有在初始化阶段调用该方法对edges做resize,直接访问edges[from]就会触发外层vector的越界,也会直接导致段错误。
修复方案

第一步:初始化edges容量

在基类构造函数或者派生类初始化逻辑中,调用get_num_nodes()初始化外层vector容量:

// 示例:在基类构造函数中添加
AdjacencyListGraphBase() {
    edges.resize(get_num_nodes());
}

第二步:修正add_edge实现逻辑

邻接表添加边需要先遍历当前起点的出边,判断目标边是否已存在,再做更新/新增操作:

void detail::AdjacencyListGraphBase::add_edge(uint32_t from, uint32_t to, float weight)
{
    // 先校验节点编号合法性,避免非法输入导致越界
    if (from >= get_num_nodes() || to >= get_num_nodes()) {
        // 可根据需求添加抛出异常、打印错误日志等逻辑
        return;
    }
    // 遍历当前起点的所有出边,查找是否已存在到to的边
    for (auto& edge : edges[from]) {
        if (edge.first == to) {
            edge.second = weight;
            return;
        }
    }
    // 没有找到对应边,新增出边
    edges[from].emplace_back(to, weight);
}
可选优化

如果你的图边修改操作频繁、节点出边数量多,可以把内层存储替换为std::unordered_map<uint32_t, float>,边查找的时间复杂度可以从O(k)(k为当前节点出边数)降到O(1),代码逻辑也更简洁:

// 替换edges的定义
std::vector<std::unordered_map<uint32_t, float>> edges;

// 优化后的add_edge逻辑
void detail::AdjacencyListGraphBase::add_edge(uint32_t from, uint32_t to, float weight)
{
    if (from >= get_num_nodes() || to >= get_num_nodes()) return;
    edges[from][to] = weight;
}

内容的提问来源于stack exchange,提问作者devGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:45:01