C++堆平衡条件修改后触发SIGSEGV运行时错误的原因咨询
堆平衡条件修改导致SIGSEGV错误的原因分析
以下是用于查找中位数的C++代码:
#include "bits/stdc++.h" using namespace std; vector<int> findMedian(vector<int> &arr, int n) { priority_queue<int> maxheap; // 存储较小元素(左半部分) priority_queue<int, vector<int>, greater<int>> minheap; // 存储较大元素(右半部分) vector<int> medians; for (int i = 0; i < n; i++) { maxheap.push(arr[i]); // 确保较小元素在maxheap中 if (minheap.size() > 0 && maxheap.top() > minheap.top()) { minheap.push(maxheap.top()); maxheap.pop(); } // 维护两个堆的大小平衡 if (minheap.size() > maxheap.size() + 1) { maxheap.push(minheap.top()); minheap.pop(); } else if (maxheap.size() > minheap.size() + 1) { minheap.push(maxheap.top()); maxheap.pop(); } // 根据元素总数奇偶性计算中位数 if ((minheap.size() + maxheap.size()) % 2 == 0) { medians.push_back((minheap.top() + maxheap.top()) / 2); } else { // 隐含else,因为大小差不超过1 if (maxheap.size() > minheap.size()) { medians.push_back(maxheap.top()); } else { // 必然是minheap.size() > maxheap.size() medians.push_back(minheap.top()); } } } return medians; }
当把堆平衡的条件语句修改为if (maxheap.size() - minheap.size() > 1)和else if (minheap.size() - maxheap.size() > 1)后,代码触发了SIGSEGV运行时错误。核心问题是忽略了C++中无符号整数的特性:
priority_queue的size()方法返回的是无符号整数类型size_t,无符号整数不支持负数运算。当被减数小于减数时,减法结果会被转换为一个极大的正数(基于无符号数的补码规则)。- 举个具体场景:假设
minheap.size()为2,maxheap.size()为0,此时maxheap.size() - minheap.size()的计算结果并非-2,而是SIZE_MAX - 1(一个远大于1的数值),导致maxheap.size() - minheap.size() > 1条件被错误触发。 - 此时代码会执行
minheap.push(maxheap.top()),但maxheap是空的,调用top()方法会触发未定义行为,最终导致SIGSEGV段错误。
而原条件maxheap.size() > minheap.size() + 1是直接进行无符号整数的大小比较,不会出现这种溢出问题,逻辑判断准确。
内容的提问来源于stack exchange,提问作者Rohit Singh
相关产品推荐
相关产品推荐

