飞鸿踏雪JX 2021-12-17 19:32
浏览 15
已结题

关于动态内存分配后释放空间的学习问题:为什么我将free置于被调函数xuanze中的被调函数INPUT后面,在INPUT执行完并返回然后遇到free后程序就自动结束了呢?


 #include<stdio.h> 
 #include<stdlib.h>
 #include<string.h>
 typedef struct student
 {
     char ID[10];
     char Name[18];
     char Sex[10];
     int English;
     int Math;
     int Computer;
     float ave;
 }STU;
void INPUT(STU *student,int o[1],int *NUM);
void AVE(STU *student,int o[1],int *NUM);
void OUTPUT(STU *student,int *NUM);
void search(STU *student,int *NUM);
void search1(STU *student,int *NUM);
void search2(STU *student,int *NUM);
void xuanze(STU *student,int o[1],int *NUM);    
void Inspect(STU *student,int o[1],int p[1],int *NUM);    
int main()
{    
    int o[1],n,*NUM;
    NUM=&n;
    printf("请输入要管理的学生人数:") ;
    scanf("%d",NUM);
    STU *student=NULL;    
    student=(struct student*)calloc(n,sizeof(struct student));//动态内存分布 
    if(student==NULL)
    {
        printf("NO enough memory!\n");
          exit(1);
    } 
     printf("\n================================学生成绩管理系统==================================\n\n");
     free(student);
    xuanze(student,o,NUM);    
     
}

void xuanze(STU *student,int o[1],int *NUM)    
{
    int choice;
     do
    {
        printf("**********************************************************************************\n\n");
        printf(" 1:输入成绩\n 2:求平均分\n 3:输出学生信息\n 4:查询\n 5:修改\n 6:排序\n 7:退出系统\n");
        printf("请选择功能:");
        scanf("%d",&choice);
        printf("**********************************************************************************\n\n");
         switch(choice)
         {
         case 1:INPUT(student,o,NUM);free(student);break;//调用输入函数 
         case 2:AVE(student,o,NUM);break;//平均分  
         case 3:OUTPUT(student,NUM);break;//输出 
        case 4:printf("\n\t有以下查询方法:\n\t1.按学号查询.\n\t2.按姓名查询.\n");search(student,NUM);//查询 
        case 5:break;//修改 
        case 6:break;//排序
        case 7:free(student);system("cls");break;//退出系统
        default:printf("-------------输入错误-------------\n");
        }
    }while(choice!=7);
}

void INPUT(STU *student,int o[1],int *NUM)
{    
    int p[1];    
    for(o[0]=0;o[0]<*NUM;o[0]+=1)//用数组o[1]作为循环变量是为了方便被调函数的实现。 
    {
        printf("\n-----------第%d位学生-----------\n",o[0]+1); 
        printf("\n学号:");
            Inspect(student,o,p,NUM);//对每一位学号是否规范输入的检查在此函数进行,并且将检查结果用p[1]来表示。p[1]其实可以用函数返回值来操作更简便,但训练为主。 
            if(strlen(((student+o[0])->ID))!=9||p[0]==0)
            {   
                printf("\n------输入错误!请输入9位数字学号!------\n");
                INPUT(student,o,NUM);
                break;/*此处break是关键,作用:当输入错误后的重新输入是正确的,则会在次级INPUT中继续后续的信息输入,
                        再跳回之前的INPUT函数中,遇到break并结束整个输入循环,避免重复输入;*/ 
            }    
        printf("\n姓名:");
            scanf("%s",((student+o[0])->Name));
        printf("\n性别:");
            scanf("%s",((student+o[0])->Sex));    
        printf("\n英语:");
            scanf("%d",&((student+o[0])->English));
        printf("\n数学:");
            scanf("%d",&((student+o[0])->Math));
        printf("\n计算机:");
            scanf("%d",&((student+o[0])->Computer));     
    }
    o[0]=2;//表示学生成绩已经成功录入; 
}

void AVE(STU *student,int o[1],int *NUM)
{
    int i;
    if(o[0]==2)//判断学生成绩是否已经录入,若未录入,则提示并跳入输入函数内; 
    {
      for(i=0;i<*NUM;i++)
        ((student+i)->ave)=(((student+i)->English)+((student+i)->Math)+((student+i)->Computer))/3.0;
      printf("平均分计算完毕,可选择3查看\n");
    }
    else {printf("-------请先录入学生成绩!-------\n\n");INPUT(student,o,NUM);} 
}

void OUTPUT(STU *student,int *NUM)
{
     int i;
     printf("|-----------------------------------------------------------------------------------------------------------------------|\n");
     printf("|\t学号\t\t|\t姓名\t|\t性别\t|\t数学\t|\t英语\t|\t计算机\t|\t平均分\t|\n");
    
    for(i=0;i<*NUM;i++)
    { 
       printf("|-----------------------------------------------------------------------------------------------------------------------|\n");
       printf("|\t%s\t|\t%s\t|\t%s\t|\t%d\t|\t%d\t|\t%d\t|\t%.2f\t|\n",student[i].ID,student[i].Name,student[i].Sex,student[i].Math,student[i].English,student[i].Computer,student[i].ave);  
    }  printf("|-----------------------------------------------------------------------------------------------------------------------|\n");
  }

void search(STU *student,int *NUM)
{
      int i;
      printf("\n\n选择查询方法:");
      scanf("%d",&i);
      switch(i)
      {
          case 1:search1(student,NUM);break;
          case 2:search2(student,NUM);break;
          default:printf("----------------不存在该选项!------------------"); search(student,NUM); 
      }    
  }

void search1(STU *student,int *NUM)
{
    char xh[10];
    int i,flag=0;
    printf("输入要查找的学号:");
    scanf("%s",xh);
    for(i=0;i<*NUM;i++)
    {
        if(strcmp(xh,((student+i)->ID))==0)
        {    
            flag=1;
            printf("\n|-----------------------------------------------------------------------------------------------------------------------|\n");
             printf("|\t学号\t\t|\t姓名\t|\t性别\t|\t数学\t|\t英语\t|\t计算机\t|\t平均分\t|\n");
            printf("|-----------------------------------------------------------------------------------------------------------------------|\n");
            printf("|\t%s\t|\t%s\t|\t%s\t|\t%d\t|\t%d\t|\t%d\t|\t%.2f\t|\n",student[i].ID,student[i].Name,student[i].Sex,student[i].Math,student[i].English,student[i].Computer,student[i].ave);  
            printf("|-----------------------------------------------------------------------------------------------------------------------|\n");
            break; 
         }
    }
    if(flag==0){printf("\n\n-------------不存在该学号的学生!---------------\n\n");search1(student,NUM);}
}

void search2(STU *student,int *NUM)
{
    char xm[10];
    int i,flag=0;
    printf("输入要查找的姓名:");
    scanf("%s",xm);
    for(i=0;i<*NUM;i++)
    {
        if(strcmp(xm,((student+i)->Name))==0)
        {    
            flag=1;
            printf("\n|-----------------------------------------------------------------------------------------------------------------------|\n");
             printf("|\t学号\t\t|\t姓名\t|\t性别\t|\t数学\t|\t英语\t|\t计算机\t|\t平均分\t|\n");
            printf("|-----------------------------------------------------------------------------------------------------------------------|\n");
            printf("|\t%s\t|\t%s\t|\t%s\t|\t%d\t|\t%d\t|\t%d\t|\t%.2f\t|\n",student[i].ID,student[i].Name,student[i].Sex,student[i].Math,student[i].English,student[i].Computer,student[i].ave);  
            printf("|-----------------------------------------------------------------------------------------------------------------------|\n");
            break; 
         }
    }
    if(flag==0) {printf("\n\n-------------不存在该姓名的学生!---------------\n\n");search2(student,NUM);}
}

void Inspect(STU *student,int o[1],int p[1],int *NUM)
{
    int ASCII,j;
    scanf("%s",((student+o[0])->ID));
            for(j=0;j<9;j++)
            {
                ASCII=((student+o[0])->ID[j]);//将一位同学的每一位学号的ASCII码值复刻出来。 
                if(ASCII<=57&&ASCII>=48)
                    p[0]=1;//如果学号是数字则用p[1]=1作为通行令。 
                else {p[0]=0;break;} //如果学号不是数字则用 p[1]=0作为违规标记,并且break掉后面几位学号的检查; 
            }
}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 12月25日
    • 创建了问题 12月17日

    悬赏问题

    • ¥15 关于stm32hal库驱动ft6336触摸屏遇到的问题
    • ¥15 需要手写数字信号处理Dsp三个简单题 不用太复杂
    • ¥15 数字信号处理考试111
    • ¥100 关于#audobe audition#的问题,如何解决?
    • ¥15 allegro17.2生成bom表是空白的
    • ¥15 请问一下怎么打通CAN通讯
    • ¥20 如何在 rocky9.4 部署 CDH6.3.2?
    • ¥35 navicat将excel中的数据导入mysql出错
    • ¥15 rt-thread线程切换的问题
    • ¥15 高通uboot 打印ubi init err 22