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

将CSV读入4096×4096二维数组时出现栈溢出(错误码3221225725)

问题:大尺寸CSV读入二维数组时程序异常终止

我参考视频编写了C语言代码,用于将CSV文件读入二维数组。处理4096×4096的数组时程序异常终止,退出码为3221225725,但100×100的矩阵能正常运行,怀疑是数组规模过大导致问题。

原代码

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define ROWS 4096
#define COLUMNS 4096

int main(void) {
  float array[ROWS][COLUMNS];

  FILE *file;

  file = fopen("Psi.csv", "r");

  if (file == NULL) {
    printf("Error opening file.\n");
    return 1;
  }

  int row = 0;

  while (!feof(file)) {
    if (ferror(file)) {
      printf("Error reading file.\n");
      return 1;
    }

      if (fscanf(file, "%f,", &array[row][i]) == EOF)
        break;
    }

    row++;

    if (row == ROWS)
      break;
  }
  fclose(file);

 
  for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLUMNS; j++)
      printf("%.1f ", array[i][j]);
    printf("\n");
  }

  return 0;
}

问题分析与解决

核心原因:栈溢出

你定义的float array[4096][4096]是栈上的局部数组,栈空间通常只有几MB(Windows默认一般是1-8MB)。每个float占4字节,4096×4096×4=67108864字节=64MB,远超栈的容量,导致栈溢出,触发程序崩溃(退出码3221225725对应Windows下的栈溢出错误)。

修复方案

方案1:动态内存分配(推荐)

在堆上分配内存,堆的容量远大于栈,适合存储大尺寸数组,同时要注意内存释放避免泄漏:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define ROWS 4096
#define COLUMNS 4096

int main(void) {
  // 动态分配二维数组:先分配行指针数组
  float **array = malloc(ROWS * sizeof(float *));
  if (array == NULL) {
    printf("Memory allocation failed for rows.\n");
    return 1;
  }

  // 为每行分配列空间
  for (int i = 0; i < ROWS; i++) {
    array[i] = malloc(COLUMNS * sizeof(float));
    if (array[i] == NULL) {
      printf("Memory allocation failed for row %d.\n", i);
      // 释放已分配的内存
      for (int j = 0; j < i; j++) {
        free(array[j]);
      }
      free(array);
      return 1;
    }
  }

  FILE *file = fopen("Psi.csv", "r");
  if (file == NULL) {
    printf("Error opening file.\n");
    // 释放内存后退出
    for (int i = 0; i < ROWS; i++) {
      free(array[i]);
    }
    free(array);
    return 1;
  }

  int row = 0;
  // 直接通过行数控制循环,替代不可靠的feof判断
  while (row < ROWS) {
    for (int col = 0; col < COLUMNS; col++) {
      // 处理最后一列没有逗号的情况
      if (col == COLUMNS - 1) {
        if (fscanf(file, "%f", &array[row][col]) != 1) break;
      } else {
        if (fscanf(file, "%f,", &array[row][col]) != 1) break;
      }
    }
    row++;
    // 跳过行尾换行符,避免影响下一行读取
    fscanf(file, "\n");
  }

  fclose(file);

  // 可选:仅输出部分数据测试,大数组全量输出会极慢
  // for (int i = 0; i < 10; i++) {
  //   for (int j = 0; j < 10; j++)
  //     printf("%.1f ", array[i][j]);
  //   printf("\n");
  // }

  // 释放动态分配的内存
  for (int i = 0; i < ROWS; i++) {
    free(array[i]);
  }
  free(array);

  return 0;
}

方案2:声明为全局变量

全局变量存储在静态存储区,不受栈空间限制,实现更简单:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define ROWS 4096
#define COLUMNS 4096

// 全局数组,存储在静态存储区,不受栈大小限制
float array[ROWS][COLUMNS];

int main(void) {
  FILE *file = fopen("Psi.csv", "r");
  if (file == NULL) {
    printf("Error opening file.\n");
    return 1;
  }

  int row = 0;
  while (row < ROWS) {
    for (int col = 0; col < COLUMNS; col++) {
      if (col == COLUMNS - 1) {
        if (fscanf(file, "%f", &array[row][col]) != 1) break;
      } else {
        if (fscanf(file, "%f,", &array[row][col]) != 1) break;
      }
    }
    row++;
    fscanf(file, "\n");
  }

  fclose(file);

  // 可选:输出测试
  // ...

  return 0;
}

额外修正点

  • 原代码中未声明变量i,在读取列的循环中必须显式声明循环变量。
  • 避免使用while(!feof(file)),这种写法容易导致最后一行重复读取或读取错误,直接通过行数控制循环更可靠。
  • 大数组的printf全量输出会非常缓慢,建议仅输出小部分数据测试。

内容的提问来源于stack exchange,提问作者Andy Duarte

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:32:39