You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++归并排序出现Vector subscript out of range错误的解决及原因咨询

嘿,我来帮你搞定这个归并排序的问题!

先搞懂两个错误的意思

1. vector subscript out of range

这个错误直白点说就是:你试图访问vector里根本不存在的位置啦!vector的下标是从0开始的,比如一个size为5的vector,有效下标是0、1、2、3、4,如果你去访问下标5,就会触发这个错误——因为这个位置没有元素。

2. 断言失败(Assertion Failed)

断言(assert)是代码里用来检查“必须满足的条件”的工具,比如你可能写了assert(index < numbers.size())来确保下标合法。当你传的参数让这个条件不成立时,程序就会触发断言失败,直接终止运行,告诉你哪里出问题了。

你的问题根源在哪里?

你调用mergeSort(numbers,0,numbers.size())的时候,把右边界传成了numbers.size(),但这个值对应的下标是不存在的(vector最后一个元素的下标是size()-1)。如果你的归并排序实现是按**闭区间[left, right]**来处理的(也就是包含left和right对应的元素),那访问numbers[right]的时候就会直接越界,同时触发断言失败。

两种解决思路

根据你的归并排序实现逻辑,选一种适配的方式:

思路1:改成闭区间调用(最常见的实现方式)

把调用改成:

mergeSort(numbers, 0, numbers.size() - 1);

同时确保你的mergeSort和merge函数是按闭区间处理的,比如参考这个实现:

#include <vector>
#include <iostream>
using namespace std;

void merge(vector<int>& nums, int left, int mid, int right) {
    // 临时数组存合并后的结果
    vector<int> temp(right - left + 1);
    int i = left, j = mid + 1, k = 0;
    
    // 合并两个有序子数组
    while (i <= mid && j <= right) {
        temp[k++] = (nums[i] <= nums[j]) ? nums[i++] : nums[j++];
    }
    // 把剩下的元素拷贝进去
    while (i <= mid) temp[k++] = nums[i++];
    while (j <= right) temp[k++] = nums[j++];
    
    // 把临时数组的内容拷回原数组
    for (int p = 0; p < temp.size(); p++) {
        nums[left + p] = temp[p];
    }
}

void mergeSort(vector<int>& nums, int left, int right) {
    // 区间只有0或1个元素,无需排序
    if (left >= right) return;
    
    int mid = left + (right - left) / 2; // 避免溢出
    mergeSort(nums, left, mid);          // 排序左半部分[left, mid]
    mergeSort(nums, mid + 1, right);     // 排序右半部分[mid+1, right]
    merge(nums, left, mid, right);       // 合并两个有序子数组
}

int main() {
    vector<int> numbers = {3,1,4,1,5,9,2,6};
    mergeSort(numbers, 0, numbers.size() - 1);
    
    for (int num : numbers) {
        cout << num << " ";
    }
    return 0;
}

思路2:适配左闭右开区间

如果你想保留mergeSort(numbers,0,numbers.size())的调用方式,那就要把实现改成左闭右开区间[left, right)(包含left,不包含right)。这种方式下,right可以是numbers.size(),因为我们不会访问这个下标:

#include <vector>
#include <iostream>
using namespace std;

void merge(vector<int>& nums, int left, int mid, int right) {
    vector<int> temp(right - left);
    int i = left, j = mid, k = 0;
    
    while (i < mid && j < right) {
        temp[k++] = (nums[i] <= nums[j]) ? nums[i++] : nums[j++];
    }
    while (i < mid) temp[k++] = nums[i++];
    while (j < right) temp[k++] = nums[j++];
    
    for (int p = 0; p < temp.size(); p++) {
        nums[left + p] = temp[p];
    }
}

void mergeSort(vector<int>& nums, int left, int right) {
    // 区间长度<=1,无需排序
    if (right - left <= 1) return;
    
    int mid = left + (right - left) / 2;
    mergeSort(nums, left, mid);    // 排序[left, mid)
    mergeSort(nums, mid, right);   // 排序[mid, right)
    merge(nums, left, mid, right); // 合并两个区间
}

int main() {
    vector<int> numbers = {3,1,4,1,5,9,2,6};
    mergeSort(numbers, 0, numbers.size());
    
    for (int num : numbers) {
        cout << num << " ";
    }
    return 0;
}
总结一下
  • 核心问题是调用的区间定义和实现逻辑不匹配,导致访问了不存在的vector下标。
  • 选一种区间方式(闭区间/左闭右开),保持调用和实现一致就解决啦!

内容的提问来源于stack exchange,提问作者Raul Marinau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:54:45