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

C++归并排序处理百万级数据崩溃问题排查及随机数疑问

归并排序处理大数据崩溃问题及rand()使用疑问

我编写的C归并排序代码可正常处理10万条int型数据,但处理100万、1000万条数据时会崩溃退出,使用DevC运行。请问代码存在什么问题?同时,当前通过rand()生成随机数的方式是否可用于其他排序算法?相关代码如下:

void merge(int arr[], int p, int q, int r) {
  int n1 = q - p + 1;
  int n2 = r - q;

  int L[n1], M[n2];

  for (int i = 0; i < n1; i++)
    L[i] = arr[p + i];
  for (int j = 0; j < n2; j++)
    M[j] = arr[q + 1 + j];

  
  int i, j, k;
  i = 0;
  j = 0;
  k = p;

  
  while (i < n1 && j < n2) {
    if (L[i] <= M[j]) {
      arr[k] = L[i];
      i++;
    } else {
      arr[k] = M[j];
      j++;
    }
    k++;
  }

  
  while (i < n1) {
    arr[k] = L[i];
    i++;
    k++;
  }

  while (j < n2) {
    arr[k] = M[j];
    j++;
    k++;
  }
}


void mergeSort(int arr[], int l, int r) {
  if (l < r) {
    int m = l + (r - l) / 2;
    mergeSort(arr, l, m);
    mergeSort(arr, m + 1, r);
    merge(arr, l, m, r);
  }
}



void printArray(int arr[], int size) {
  for (int i = 0; i < size; i++)
    cout << arr[i] << " ";
  cout << endl;
}




int main()
{
    int n;
    cout << "Enter Number: ";
    cin >> n;
   int array[n];
   for(int i = 0; i<n; i++) {
      array[i]=rand()%1000;
   }


auto start2 = chrono::steady_clock::now();
  mergeSort(array, 0, n - 1);
 auto end2 = chrono::steady_clock::now();
auto diff2 = end2 - start2;
cout << "Time to sort for Merge: "<<chrono::duration <double, milli> (diff2).count() << " ms" << endl;

    return 0;
}

一、代码崩溃的核心原因及修复方案

1. 栈溢出是主因

你的代码里有两处致命的栈内存滥用:

  • main函数中的int array[n];:这是变长数组,直接在栈上分配。栈的默认大小通常只有1~8MB,100万个int需要4MB(刚好踩线),1000万个int需要40MB,远超栈的容量,直接触发栈溢出崩溃。
  • merge函数中的int L[n1], M[n2];:归并排序递归调用时,每个merge都会在栈上分配两个临时数组,递归层数叠加后,栈的占用会进一步飙升,加速崩溃。

另外补充:C标准里根本不支持变长数组,这是GCC的扩展特性,DevC用MinGW编译才允许,但这种写法本身就不标准,移植性差且风险极高。

2. 修复方案

把所有栈上的变长数组改成堆内存分配,推荐用C++的vector(自动管理内存,避免泄漏):

  • 将main里的int array[n];改为vector<int> array(n);
  • 将merge里的int L[n1], M[n2];改为vector<int> L(n1), M(n2);

如果坚持用C风格写法,就用new/delete手动分配堆内存:

int* L = new int[n1];
int* M = new int[n2];
// ... 原有逻辑 ...
delete[] L;
delete[] M;

二、rand()生成随机数对其他排序算法的适用性

1. 可以用于大多数测试场景

你当前用rand()%1000生成0~999的重复随机数,完全可以用来测试冒泡、快速、插入、希尔等绝大多数排序算法:

  • 能验证排序算法的正确性(是否能把乱序数组排好)
  • 能测试算法的基本性能(对比不同算法的耗时)

2. 存在的局限性

  • 随机数范围太小:如果要测试排序算法的最坏情况(比如快速排序的极端有序/逆序场景),rand()%1000生成的重复值太多,无法模拟这种极端情况,需要调整生成逻辑(比如生成全范围int值,或者手动构造有序序列)。
  • 随机性不足:rand()的伪随机数周期短、质量一般,对于学术研究级别的性能对比,建议用C++11引入的<random>库(比如mt19937生成器),随机性更好,周期更长。
  • 未初始化种子:当前代码没调用srand(time(nullptr)),每次运行生成的随机数序列完全一样,若需要不同的测试序列,记得在main开头加上这句代码。

内容的提问来源于stack exchange,提问作者nima karami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:10:33