C++二维vector用引用触发heap-use-after-free问题排查
解决合并区间问题中的
AddressSanitizer: heap-use-after-free错误 问题根源
你的代码触发内存错误主要有两个关键问题:
- 未处理空输入边界:当传入的
intervals是空数组时,vector<vector<int>> mergedIntervals(1, intervals[0]);直接访问intervals[0],属于数组越界,会触发未定义行为,表现为heap-use-after-free或EXC_BAD_ACCESS。 - 缺少区间排序步骤:合并区间的核心前提是区间按起始值升序排列,没有排序的话不仅会导致合并逻辑错误,还可能在极端输入下引发内存相关的异常。
你提到每次修改mergedIntervals后都更新了引用,但初始阶段的越界访问已经足以触发错误,这是容易忽略的点。
修复后的完整代码
#include <stdio.h> #include <vector> #include <algorithm> using namespace std; class Solution { public: vector<vector<int>> merge(vector<vector<int>>& intervals) { // 先处理空输入的情况 if (intervals.empty()) { return {}; } // 按区间起始值升序排序,这是合并的必要前提 sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) { return a[0] < b[0]; }); vector<vector<int>> mergedIntervals; mergedIntervals.push_back(intervals[0]); vector<int>& currentMergedInterval = mergedIntervals.back(); for (size_t i = 1; i < intervals.size(); i++) { int mergedEnd = currentMergedInterval[1]; int currStart = intervals[i][0]; int currEnd = intervals[i][1]; if (mergedEnd >= currStart) { // 合并时取两个区间结束值的最大值,避免覆盖成更小的值 currentMergedInterval[1] = max(mergedEnd, currEnd); } else { mergedIntervals.push_back(intervals[i]); currentMergedInterval = mergedIntervals.back(); } } return mergedIntervals; } }; int main() { Solution s; vector<vector<int>> v = {{1,3}, {2,6}, {8,10}, {15,18}}; vector<vector<int>> sol = s.merge(v); // 预期输出: [[1,6],[8,10],[15,18]] for (const vector<int>& vec : sol) { printf("%d %d\n", vec[0], vec[1]); } // 测试空输入场景 vector<vector<int>> emptyInput; vector<vector<int>> emptyResult = s.merge(emptyInput); printf("Empty input result: %zu intervals\n", emptyResult.size()); }
核心修复说明
- 空输入防护:在函数开头判断输入是否为空,直接返回空数组,彻底避免越界访问的问题。
- 强制区间排序:通过
sort和lambda表达式对区间排序,保证后续合并逻辑的正确性。 - 优化合并逻辑:合并时取两个区间结束值的最大值,修复原代码中直接覆盖为当前区间结束值的错误(比如原区间结束值更大的情况)。
内容的提问来源于stack exchange,提问作者John Boccio
相关产品推荐
相关产品推荐

