将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
相关产品推荐
相关产品推荐

