You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;主函数中误用函数声明

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:45:35