最长递增子序列代码简化后触发0xC0000005错误求助
问题根源:条件判断顺序错误导致的非法内存访问
你遇到的0xC0000005错误(Windows下的内存访问冲突/段错误),核心原因是简化代码时颠倒了条件判断的顺序,导致程序尝试访问空vector的back()方法,触发了未定义行为。
具体分析:
原代码的逻辑是安全的:它会先检查pile[j].size() == 0,只有当堆不为空时,才会去访问pile[j].back()做比较:
if(pile[j].size() == 0) { // 处理空堆的插入逻辑 } else if(a[pile[j].back()] < a[i]) { // 继续下一个堆 } else { // 插入当前堆 }
但你简化后的代码把a[pile[j].back()] > a[i]放在了||的左侧:
if(a[pile[j].back()] > a[i] || pile[j].size() == 0) { // 插入逻辑 }
逻辑或||的执行规则是先判断左侧条件,只有左侧为假时才会判断右侧。当pile[j]为空时,程序会先执行左侧的a[pile[j].back()]——这时候访问空vector的back()方法,直接越界访问内存,导致系统抛出内存访问错误。
修复方案:
调换条件顺序,利用逻辑或的短路特性,先检查堆是否为空:
if(pile[j].size() == 0 || a[pile[j].back()] > a[i]) { printf("push %d to pile %d\n", a[i], j); pile[j].push_back(i); prev[i] = (j == 0)? -1 : pile[j-1].back(); m = max(j, m); break; }
这样当pile[j].size() == 0为真时,右侧的a[pile[j].back()]不会被执行,避免了非法内存访问,同时逻辑和原代码完全一致。
额外优化建议(非错误相关):
原代码中for(int j=0; j<s; j++)的遍历范围太大,因为堆的数量最多不会超过LIS的长度(也就是m+1),可以改成遍历到m+1,减少不必要的循环次数:
for(int j=0; j<=m+1; j++) { // ... 原有逻辑 }
内容的提问来源于stack exchange,提问作者Anakin
相关产品推荐
相关产品推荐

