C程序输入n大于2时触发malloc内存损坏错误求助
几何图形处理C程序内存错误排查与修复
问题描述
编写的几何图形处理C程序在输入图形数量n>2时触发错误:malloc(): corrupted top size Aborted (core dumped),现提供完整代码、输入输出格式及测试用例,需排查并解决该问题。
完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <stdbool.h> struct Geometry { bool isrectangle, isquare, isline, iscircle; float x1, x2, y1, y2; float square_corner1, square_corner2, side; float center1, center2, radius; float rectangle_corner1, rectangle_corner2, width, height; }; #define SCANF_FMT_CIRCLE "%f %f %f" #define SCANF_FMT_RECTANGLE "%f %f %f %f" #define SCANF_FMT_SQUARE "%f %f %f" #define SCANF_FMT_LINE "%f %f %f %f" #define PRINTF_FMT_CIRCLE "Circle with center at %f, %f and radius %f\n" #define PRINTF_FMT_RECTANGLE "Rectangle with corner at (%f, %f) with width %f and height %f\n" #define PRINTF_FMT_SQUARE "Square with corner at (%f, %f) and side %f\n" #define PRINTF_FMT_LINE "Line from (%f, %f) to (%f, %f)\n" void initRectangle(struct Geometry **object){ scanf(SCANF_FMT_RECTANGLE, &((*object)->rectangle_corner1), &((*object)->rectangle_corner2), &((*object)->width), &((*object)->height)); (*object)->isrectangle = true; (*object)->iscircle = false; (*object)->isquare = false; (*object)->isline = false; } void initSquare(struct Geometry **object){ scanf(SCANF_FMT_SQUARE, &((*object)->square_corner1), &((*object)->square_corner2), &((*object)->side)); (*object)->isrectangle = false; (*object)->iscircle = false; (*object)->isquare = true; (*object)->isline = false; } void initCircle(struct Geometry **object){ scanf(SCANF_FMT_CIRCLE, &((*object)->center1), &((*object)->center2), &((*object)->radius)); (*object)->isrectangle = false; (*object)->iscircle = true; (*object)->isquare = false; (*object)->isline = false; } void initLine(struct Geometry **object){ scanf(SCANF_FMT_LINE, &((*object)->x1), &((*object)->x2), &((*object)->y1), &((*object)->y2)); (*object)->isrectangle = false; (*object)->iscircle = false; (*object)->isquare = false; (*object)->isline = true; } void printGeometry(struct Geometry* object){ if (object->iscircle == true){ printf(PRINTF_FMT_CIRCLE, object->center1, object->center2, object->radius); } else if (object->isline == true){ printf(PRINTF_FMT_LINE, object->x1, object->x2, object->y1, object->y2); } else if (object->isquare == true){ printf(PRINTF_FMT_SQUARE, object->square_corner1, object->square_corner2, object->side); } else { printf(PRINTF_FMT_RECTANGLE, object->rectangle_corner1, object->rectangle_corner2, object->width, object->height); } } void freeGeometry(struct Geometry* object){ free(object); object = NULL; } int main() { int n; struct Geometry **object; scanf("%d", &n); printf("%d geometric items\n", n); object = malloc(sizeof(struct Geometry*)*n); for(int i = 0; i < n; i++) { object[i] = malloc(sizeof(struct Geometry *)*n); char objectType[40]; scanf("%s", objectType); if(!strcmp(objectType, "Rectangle")) { initRectangle(&object[i]); } else if (!strcmp(objectType, "Square")) { initSquare(&object[i]); } else if(!strcmp(objectType, "Circle")) { initCircle(&object[i]); } else if(!strcmp(objectType, "Line")) { initLine(&object[i]); } else { printf("Unknown geometric type %s\n", objectType); exit(1); } } for(int i = 0; i < n; i++) { printGeometry(object[i]); } for(int i = 0; i < n; i++) { freeGeometry(object[i]); } free(object); }
输入格式
6 Line 0.739 0.053 0.380 0.383 Line 0.098 0.158 0.546 0.531 Square 0.120 0.707 0.346 Rectangle 0.769 0.041 0.995 0.859 Rectangle 0.671 0.520 0.246 0.226 Square 0.333 0.721 0.249
预期输出格式
6 geometric items Line from (0.739000, 0.053000) to (0.380000, 0.383000) Line from (0.098000, 0.158000) to (0.546000, 0.531000) Square with corner at (0.120000, 0.707000) and side 0.346000 Rectangle with corner at (0.769000, 0.041000) with width 0.995000 and height 0.859000 Rectangle with corner at (0.671000, 0.520000) with width 0.246000 and height 0.226000 Square with corner at (0.333000, 0.721000) and side 0.249000
错误信息
malloc(): corrupted top size Aborted (core dumped)
问题根源
核心错误出在单个几何对象的内存分配步骤:
object[i] = malloc(sizeof(struct Geometry *)*n);
此处错误分配了n个指针大小的内存,而非单个struct Geometry结构体的实际大小。当n>2时,分配的内存远小于结构体所需空间,后续对结构体成员的写入操作会越界覆盖堆内存元数据,触发malloc()的完整性检查,导致程序崩溃。
修复方案
将单个对象的分配代码修改为:
object[i] = malloc(sizeof(struct Geometry));
或更安全的写法(避免类型写错):
object[i] = malloc(sizeof(*object[i]));
额外优化建议
内存分配检查:每次
malloc后需检查返回值是否为NULL,避免空指针访问:object = malloc(sizeof(struct Geometry*)*n); if (object == NULL) { perror("Failed to allocate array"); exit(1); } // ... object[i] = malloc(sizeof(struct Geometry)); if (object[i] == NULL) { perror("Failed to allocate Geometry object"); // 释放已分配的内存,避免泄漏 for (int j = 0; j < i; j++) { free(object[j]); } free(object); exit(1); }freeGeometry函数优化:当前函数内将
object设为NULL的操作对外部无影响(参数为值传递),可修改为指针的指针:void freeGeometry(struct Geometry **object){ if (*object != NULL) { free(*object); *object = NULL; } } // 调用时:freeGeometry(&object[i]);
内容的提问来源于stack exchange,提问作者Anshul Mehta
相关产品推荐
相关产品推荐

