C语言统计程序运行出现Segmentation Fault错误求助
C程序段错误(Segmentation Fault)排查与修复
问题背景
编译运行一个从.dat文件读取结构体数据并累积统计的C程序时,出现Segmentation Fault错误。尝试通过printf查看i、j、k变量值,且减少处理的结构体数量(从500个改为少于50个),问题仍未解决。
相关代码
主程序代码
#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> #include <windows.h> struct persona { int edad; //EDAD DE 12-65// int notas; //NOTAS DE 0-10// char sexo; //SEXO 1=MASCULINO Y 2=FEMENINO// char exi; //EXI 1=SI 2=NO }; struct reg { int notas; int contex; int cont; }; const int imax = 7; const int jmax = 6; const int kmax = 3; struct reg A[imax][jmax][kmax]; void retardo() { for(int i=0; i < 11000; i++) { for(int j=0; j < 11000; j++) { } } } void processbar() { system("pause"); system("cls"); int i, j; for(i=0; i < 20 ; i++) { printf("Cargando... \n"); printf("====================\n"); for(j=0; j < i ; j++) { printf("X"); } printf("\n====================\n"); retardo(); system("cls"); } } void etario(int j, char grupoed[10]) //ASIGNAMOS LOS RANGOS ETARIOS// { switch(j) { case(1): grupoed ="12-15"; break; case(2): grupoed ="16-25"; break; case(3): grupoed ="26-35"; break; case(4): grupoed ="36-45"; break; case(5): grupoed ="46-55"; break; case(6): grupoed = "56-65"; default: printf("\nHa ocurrido un error"); } } void grupoed(struct persona p, int j) { if( p.edad < 12) { printf("\nexiste un error en la edad"); } if(p.edad < 16) { j = 1; } if(p.edad < 26) { j = 2; } if(p.edad < 36) { j = 3; } if(p.edad < 46) { j = 4; } if(p.edad < 56) { j = 5; } if(p.edad < 66) { j = 6; } else { printf("\nexists un error en la edad"); } } void niveling(struct persona p, int i) { if(p.notas < 2) { i = 1; } if(p.notas < 4) { i = 2; } if(p.notas < 6) { i = 3; } if(p.notas < 8) { i = 4; } if(p.notas < 10) { i = 5; } } void femasc(struct persona p, int k) { if(p.sexo = 'M') { k = 1; } else { if(p.sexo = 'F') { k = 2; } } } void matrizcero(struct reg A[imax][jmax][kmax], int i, int j, int k) { for (i = 1; i < 7; i++) { for (j = 1; i < 6; j++) { for (k = 1; i < 3; k++) { A[i][j][k] = {0,0,0}; } } } } int main() { struct reg A[imax][jmax][kmax]; void processbar(); void matrizcero(struct reg A[imax][jmax][kmax], int i, int j, int k); struct persona p; struct reg; int i, j, k,rangomay, rangomen, rangointmay, resmay, resmen, jex, jmay, jmen, NIV, GRUPOET, sexo, cantidadM, califM, cantidadF, califF, grupoetario; char grupoed[10]; float prom_m, prom_f; FILE *entrada; //ABRO ARCHIVO entrada=fopen("datospersonas.dat","rb"); if (entrada == NULL){ exit(1); printf("\nError al abrir el archivo"); } else { printf("\nArchivo abierto exitosamente!"); } while(!(feof(entrada))){ void niveling(struct persona p, int i); void grupoedad(struct persona p, int j); void femasc(struct persona p, int k); printf("\n%d",i); printf("\n%d",j); printf("\n%d",k); A[i][j][k].notas = A[i][j][k].notas + p.notas; A[i][j][k].cont = A[i][j][k].cont; if(p.exi = 'S') { A[i][j][k].contex = A[i][j][k].contex + 1; } fread(&p,sizeof(p),1,entrada); //LEO ARCHIVO } for(i = 1; i < 6; i++) { //TOTALIZO HOMBRES Y MUJERES for(j = 1; i < 7; i++) { A[i][j][3].notas = A[i][j][3].notas + A[i][j][2].notas; A[i][j][3].cont = A[i][j][3].cont + A[i][j][2].cont; A[i][j][3].contex = A[i][j][3].contex + A[i][j][2].contex; } } for(j = 1; j < 7; j++) { for(i = 1; i < 6; i++) { cantidadM = cantidadM + A[i][j][1].cont; califM = califM + A[i][j][1].notas; } } prom_m = califM / cantidadM; //PROMEDIO DE CALIFICACIONES DE LOS HOMBRES for(j = 1; j < 7; j++) { for(i = 1; i < 6; i++) { cantidadF = cantidadF + A[i][j][2].cont; califF = califF + A[i][j][2].notas; } } prom_f = califF / cantidadM; //PROMEDIO DE CALIFICACIONES MUJERES for(k = 1; k < 3; k++) { for(i = 1; i < 6; i++) { for(j = 1; j < 7; j++) { A[6][j][k].cont = A[6][j][k].cont + A[i][j][k].cont; A[6][j][k].contex = A[6][j][k].contex + A[i][j][k].cont; A[6][j][k].notas = A[6][j][k].notas + A[i][j][k].notas; } } } for(j = 1; j < 7; j++) { A[6][j][3].cont = A[6][j][1].cont + A[6][j][2].cont; A[6][j][3].cont = A[6][j][1].contex + A[6][j][2].contex; A[6][j][3].notas = A[6][j][1].notas + A[6][j][2].notas; } resmay = A[6][1][3].contex; for(j = 1; j < 7; j++) { if(A[6][j][3].contex > resmay) { resmay = A[6][j][3].contex; jex = j; } } for(k = 1; k < 3; k++) { for(j = 1; j < 7; j++) { A[7][j][k].notas = A[6][j][k].notas / A[6][j][k].cont; } } resmen = A[7][1][3].notas; resmay = A[7][1][3].notas; for(j = 1; j < 7; j++) { if(A[7][j][3].notas > resmay) { resmay = A[7][j][3].notas; jmay = j; } else { if(A[7][j][3].notas < resmen) { resmen = A[7][j][3].notas; jmen = j; } } } void etario(int jmay); printf("\nEl rango etario con mayor calificacion en promedio fue el comprendido entre: %s", grupoed, " años"); void etario(int jmen); printf("\nEl rango etario con menor calificacion en promedio fue el comprendido entre: %s", grupoed, " años"); printf("\nEl promedio de calificaciones en femeninos fue: %f", prom_f); printf("\nEl promedio de calificaciones en masculinos fue: %f", prom_m); void etario(int jex); printf("\nEl rango etario con mayor interes en rendir examenes internacionales es el comprendido entre: %s", grupoed, "años"); fclose(entrada); system("pause"); return 0; }
生成.dat文件的程序代码
#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> struct persona { int edad; //EDAD DE 12-65// int notas; //NOTAS DE 0-10// char sexo; //SEXO 1=MASCULINO Y 2=FEMENINO// char exi; //EXI 1=SI 2=NO }; void generacion() { FILE *entrada; entrada=fopen("datospersonas.dat","w+"); if (entrada == NULL){ exit(1); } fclose(entrada); } int main() { int s; int exi; generacion(); persona p; FILE* entrada; entrada=fopen("datospersonas.dat","w+"); for (size_t i=0;i<30; i++) { p.edad =(rand() %53)+12; p.notas =(rand() %9)+1; s=(rand() %2)+1; if(s == 1){ p.sexo='M'; } else{ p.sexo='F'; } exi=(rand() %2)+1; if(exi == 1){ p.exi='S'; } else{ p.exi='N'; } fwrite(&p, sizeof(struct persona),1,entrada); printf("edad: %d\n",p.edad); printf("nota: %d\n",p.notas); printf("sexo: %c\n",p.sexo); printf("esta interesado en rendir examenes internacionales: %c\n",p.exi); } fclose(entrada); return 0; }
错误根源与修复方案
1. 未初始化变量导致非法内存访问
主函数中i、j、k等局部变量未初始化,直接用于数组索引A[i][j][k],会触发段错误;cantidadM、califM等累加变量未初始化,会导致统计结果错误。
- 修复:使用前初始化变量:
int i=0, j=0, k=0, ..., cantidadM=0, califM=0, cantidadF=0, califF=0;
2. 函数参数传递错误(值传递无法修改外部变量)
grupoed、niveling、femasc等函数用值传递参数,内部修改的j、i、k无法同步到主函数,导致主函数中变量为随机值,引发数组越界。
- 修复:改为指针传递,例如修改
grupoed函数:
void grupoed(struct persona p, int *j) { if( p.edad < 12) { printf("\nexiste un error en la edad"); *j = -1; return; } if(p.edad < 16) { *j = 1; } else if(p.edad < 26) { *j = 2; } else if(p.edad < 36) { *j = 3; } else if(p.edad < 46) { *j = 4; } else if(p.edad < 56) { *j = 5; } else if(p.edad < 66) { *j = 6; } else { printf("\n存在年龄错误"); *j = -1; } }
主函数调用时传入地址:grupoed(p, &j);
3. 循环条件错误
matrizcero及主函数中多个嵌套循环条件错误,例如内层循环误用外层变量的判断条件,导致循环逻辑混乱。
- 修复:修正循环条件,例如
matrizcero函数:
void matrizcero(struct reg A[imax][jmax][kmax]) { for (int i = 1; i < imax; i++) { for (int j = 1; j < jmax+1; j++) { for (int k = 1; k < kmax+1; k++) { A[i][j][k] = {0,0,0}; } } } }
4. 赋值与比较运算符混淆
多处用=赋值代替==比较,例如if(p.sexo = 'M'),会修改变量值并导致逻辑错误。
- 修复:改为
==比较:
if(p.sexo == 'M') if(p.exi == 'S')
5. 文件操作顺序错误
while循环中先使用未初始化的p再读取数据,导致第一次循环使用垃圾数据。
- 修复:先读取再处理,用
fread返回值判断是否读取成功:
while(fread(&p,sizeof(p),1,entrada) == 1){ niveling(p, &i); grupoed(p, &j); femasc(p, &k); if(i >=1 && i < imax && j >=1 && j <=jmax && k >=1 && k <=kmax){ A[i][j][k].notas += p.notas; A[i][j][k].cont += 1; if(p.exi == 'S') { A[i][j][k].contex += 1; } } }
6. 数组越界访问
A[7][j][k]超出数组定义范围(imax=7,索引范围0-6),导致非法内存访问。
- 修复:调整数组大小为
imax=8,或修改统计行索引为6。
7. 函数调用与字符串赋值错误
etario函数中直接给字符数组赋值字符串字面量无效,需用strcpy;主函数中误用函数声明
相关产品推荐
相关产品推荐

