C语言动态分配两个同列宽二维数组时出现malloc corrupted top size报错
动态二维数组malloc堆损坏报错修复
报错根因
malloc(): corrupted top size是glibc堆检测机制发现堆内存元数据被破坏后抛出的运行时错误,本次问题的直接诱因是动态内存申请时的字节数计算错误,引发越界写入踩踏堆内存。
代码核心问题点
- 二级指针数组申请大小错误:需要存储的行指针类型为
double *,但代码中使用sizeof(int *)计算每个行指针的占用空间,若平台上int *和double *宽度不一致,会直接导致二级指针数组溢出 - 每行数据数组申请大小错误(触发报错的核心原因):需要存储的元素是
double类型(通常占8字节),但代码中用sizeof(int)(通常占4字节)计算每行所需空间,相当于每行只申请了实际需求一半的内存,写入double数据时会直接越界覆盖相邻堆的元数据,最终触发报错 - 缺少参数合法性校验:未校验传入的行、列数是否满足>=1的要求,不符合「两个数组行数至少包含1行」的预期
修正后代码
double **createSyntheticReference(int rows, int columns) { // 合法性校验,保证行、列数至少为1 if (rows < 1 || columns < 1) { return NULL; } int i,j; // 修正行指针数组的申请大小:每个元素为double* double **student = malloc(rows * sizeof(double *)); for (i = 0; i < rows; i++) { // 修正每行数据的申请大小:每个元素为double student[i] = malloc(columns * sizeof(double)); } // 原有数据加载逻辑保持不变 for(i=0; i<rows;i++) { for(j=0; j<columns; j++) { student[i][j] = rand()%100+1; } } // 原有打印逻辑保持不变 for(i=0; i<rows; i++) { printf("%lf", student[i][0]); for(j=1; j<columns; j++) { printf("%17lf", student[i][j]); } puts(""); } return student; } double **createSyntheticQuery(int columns) { if (columns < 1) { return NULL; } int i,j; int rows = 10; // 若需要动态指定行数可新增入参,此处保留原有硬编码逻辑 // 修正行指针数组的申请大小 double **query = malloc(rows * sizeof(double *)); for (i = 0; i < rows; i++) { // 修正每行数据的申请大小 query[i] = malloc(columns * sizeof(double)); } // 原有数据加载、打印逻辑保持不变 for(i=0; i<rows;i++) { for(j=0; j<columns; j++) { query[i][j] = rand()%100+1; } } for(i=0; i<rows; i++) { printf("%lf", query[i][0]); for(j=1; j<columns; j++) { printf("%17lf", query[i][j]); } puts(""); } return query; }
开发提示:后续排查内存类问题时,可使用
valgrind工具检测内存越界、泄漏问题,能快速定位堆破坏的根源。
内容的提问来源于stack exchange,提问作者Programmer_007
相关产品推荐
相关产品推荐

