C语言代码输入A点坐标正常,输入B点坐标时触发总线错误崩溃
问题根因
程序崩溃的核心原因是未给结构体内部的指针成员分配有效内存就直接解引用写入,属于野指针触发的未定义行为。
- 你定义的
struct triangle中,A、B、C三个成员是struct point*类型的指针,而非struct point类型的实体变量。 - 你在
main函数中仅创建了struct triangle triangle1实例,让trianglePtr指向了这块有效内存,但从来没有为A、B、C三个指针本身分配它们需要指向的struct point类型内存空间。这三个指针此时存储的是栈上残留的随机垃圾值,属于野指针。 - 输入A点坐标时没有立刻崩溃,只是因为A指针存储的随机值刚好指向了一块当前进程有写入权限的内存,这部分写入已经属于非法篡改未知内存的未定义行为;等写入B指针指向的地址时,该地址属于系统保护的不可写区域,直接触发
bus error崩溃。
修复方案
二选一即可:
方案1:保留指针成员,提前分配堆内存
如果业务逻辑确实需要用指针存储三个点,在读写指针指向的内容前,先通过malloc给三个指针分配有效内存:
void initialiseTriangle(struct triangle *object) { // 先为三个点指针申请对应大小的堆内存 object->A = malloc(sizeof(struct point)); object->B = malloc(sizeof(struct point)); object->C = malloc(sizeof(struct point)); // 生产环境需要判断malloc返回值是否为NULL,处理内存申请失败的场景 printf("Give Coordinates...\n"); printf("Give A(x1,y1): \n"); scanf("%d", &object->A->x); scanf("%d", &object->A->y); printf("Give B(x2,y2): \n"); scanf("%d", &object->B->x); scanf("%d", &object->B->y); printf("Give C(x3,y3): \n"); scanf("%d", &object->C->x); scanf("%d", &object->C->y); // 后续使用完三角形结构体后,需要手动free三个点的内存,避免内存泄漏 }
方案2:去掉不必要的指针,直接用结构体实体
如果没有跨作用域共享点变量、动态扩展的需求,直接把triangle的成员改成结构体实例是最简单稳妥的写法,不需要手动管理内存,也不会出现野指针问题:
- 修改结构体定义:
struct triangle { struct point A; struct point B; struct point C; }; - 对应修改
initialiseTriangle里的取地址逻辑,把&object->A->x改成&object->A.x即可,其余逻辑不变。
内容的提问来源于stack exchange,提问作者Ανδρέας Γκόγκος
相关产品推荐
相关产品推荐

