std::sort自定义比较函数引发堆缓冲区溢出的原因探究
按奇偶排序数组:std::sort自定义比较函数的问题分析
在LeetCode《按奇偶排序数组》的解题过程中,两个自定义比较函数的表现差异,本质是是否满足std::sort要求的严格弱序规则,具体差异和问题原因如下:
错误的比较函数
bool cmp(int a, int b) { return a % 2 == 0; }
这个函数的逻辑是“只要a是偶数就返回true”,完全不符合std::sort对比较函数的核心要求——严格弱序:
- 违反非对称性:当a和b都是偶数时,
cmp(a,b)和cmp(b,a)都会返回true,这意味着排序算法会认为“a应该排在b前面,同时b也应该排在a前面”,逻辑矛盾。 - 等价判断混乱:当a和b都是奇数时,
cmp(a,b)和cmp(b,a)都返回false,算法会认为两者等价,但实际排序过程中这种错误的等价判断会打乱内部排序逻辑(比如快速排序的分区、堆排序的堆调整)。
小测试用例可能刚好没触发内存越界,但大测试用例下,算法逻辑混乱会导致非法内存访问,最终触发heap-buffer-overflow错误。
正确的比较函数
bool cmp(int a, int b) { return a % 2 == 0 && b % 2 == 1; }
这个函数的逻辑是“仅当a是偶数且b是奇数时,a排在b前面”,完全满足严格弱序的要求:
- 自反性:
cmp(a,a)永远返回false,符合“元素不能排在自己前面”的规则。 - 非对称性:如果
cmp(a,b)为true(a偶b奇),那么cmp(b,a)必然为false(b奇a偶,不满足条件)。 - 传递性:所有排序关系的推导都符合逻辑,比如若a偶b奇、b奇c奇,则a偶c奇,
cmp(a,c)也为true。
这种明确的排序规则能让std::sort正确完成“偶数在前、奇数在后”的排序需求,所有测试用例都能正常通过。
完整代码示例
// bool cmp(int a, int b) { // return a % 2 == 0; // }//wrong method // bool cmp(int a, int b) { // return a % 2 == 0 && b % 2 == 1; // }//AC method class Solution { public: vector<int> sortArrayByParity(vector<int>& nums) { sort(nums.begin(),nums.end(),cmp); return nums; } };
内容的提问来源于stack exchange,提问作者LouieK
相关产品推荐
相关产品推荐

