为何以下C程序会出现segmentation fault(段错误)?
问题分析与修复方案
先把你的代码贴出来,方便咱们一起看:
int main() { int i; struct student* a[4]; a[0]->id = 20; a[0]->age= 22; a[1]->id = 23; a[1]->age= 24; a[2]->id = 25; a[2]->age= 26; a[3]->id = 27; a[3]->age= 28; for(i=0;i<4;i++) { printf("%d %d \n",a[i]->id,a[i]->age); } return 0; }
核心问题:野指针导致的未定义行为
你定义的struct student* a[4];是一个指针数组,数组里的每个元素都是指向struct student类型的指针,但这些指针在声明后完全没初始化——它们指向的是内存里的随机位置(也就是常说的「野指针」)。
为什么移除循环直接打印可能没崩溃?这纯粹是运气:碰巧你访问的那块随机内存区域暂时没被系统保护,或者没触发内存冲突,但这绝对不是代码正确,属于未定义行为——今天能跑,明天说不定就崩,换个编译器或系统直接炸锅。
而用for循环时出现段错误,只是未定义行为的另一种表现:循环过程中访问的某块随机内存刚好被系统标记为不可访问,直接触发了段错误。本质上两种写法都是错的,只是崩溃时机不同而已。
两种靠谱的修复方案
方案1:给每个指针分配堆内存
用malloc为每个指针申请对应的结构体内存,记得用完要释放避免内存泄漏:
#include <stdio.h> #include <stdlib.h> // 先补上你漏写的结构体定义 struct student { int id; int age; }; int main() { int i; struct student* a[4]; // 给每个指针分配内存,同时检查分配是否成功 for(i=0;i<4;i++) { a[i] = malloc(sizeof(struct student)); if(a[i] == NULL) { perror("malloc failed"); return 1; } } // 赋值 a[0]->id = 20; a[0]->age= 22; a[1]->id = 23; a[1]->age= 24; a[2]->id = 25; a[2]->age= 26; a[3]->id = 27; a[3]->age= 28; // 打印 for(i=0;i<4;i++) { printf("%d %d \n",a[i]->id,a[i]->age); } // 释放堆内存 for(i=0;i<4;i++) { free(a[i]); } return 0; }
方案2:直接定义结构体数组(更简单)
如果不需要动态内存,直接定义struct student类型的数组,每个元素都是完整的结构体,不用额外分配内存:
#include <stdio.h> struct student { int id; int age; }; int main() { int i; struct student a[4]; // 直接定义结构体数组 // 注意这里用.而不是->,因为a[i]是结构体实例不是指针 a[0].id = 20; a[0].age= 22; a[1].id = 23; a[1].age= 24; a[2].id = 25; a[2].age= 26; a[3].id = 27; a[3].age= 28; // 打印 for(i=0;i<4;i++) { printf("%d %d \n",a[i].id,a[i].age); } return 0; }
额外提醒
你的原代码还漏了struct student的定义,这在编译阶段就会报错,我在修复代码里补上了,以后写结构体相关代码一定要先定义结构体类型哦!
内容的提问来源于stack exchange,提问作者SHUBHAM TANDAN
相关产品推荐
相关产品推荐

