C++邻接表实现中向pair型vector添加元素触发SIGSEGV段错误
问题分析
你遇到的段错误由两个核心问题共同导致:
- 邻接表访问逻辑完全错误
你定义的edges是标准邻接表结构:内层std::vector<std::pair<uint32_t, float>>存储单个起点的所有出边集合,每个元素是(目标节点编号, 边权重),你直接用目标节点编号to作为内层vector的下标访问,本质是把邻接表当成了邻接矩阵使用。只要to的数值大于内层vector的长度,就会触发越界访问,这是段错误的核心诱因。 - 未初始化
edges的外层容量
外层edgesvector的长度需要和图的总节点数保持一致,你类中已经定义了纯虚函数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
相关产品推荐
相关产品推荐

