编了个链表的成绩管理系统 能通过编译 运行时出错了解决方法

编了个链表的成绩管理系统 能通过编译 运行时出错了
C/C++ code
// 学生成绩管理系统.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"

#define N 2

typedef struct node
{
    char *name;  //学生的姓名
    int num;   //学生的学号
    int score;  //学生的分数
    struct node *next;
}student;

int i;

//新建函数
student * initial(student * stu)
{
    student *p,*q;
    p=(student *)malloc(sizeof(student));
    //stu->next=p;
    stu=p;
    
    for(i=1;i<=N;i++)
    {
        q=(student *)malloc(sizeof(student));
        printf("第%d个学生的信息:姓名  学号 分数\n",i);
        scanf("%c%d%d",&q->name,&q->num,&q->score);
        printf("\n");
        p=q;
        p->next=(student *)malloc(sizeof(student));  
        p=p->next;
        p->next=NULL;
        free(q);

    }
    free(p);
    return stu;

}


//输出函数
void print(student * stu)
{
   
    /*student *p;
    p=stu->next;
    
    for(i=1;(i<=4)&&(p->next);i++,p=p->next)
    {
        p=(student *)malloc(sizeof(student));
        printf("第%d个学生的信息:姓名%5c  学号%5d 分数%5d\n",i,p->name,p->num,p->score);
        p->next=(student *)malloc(sizeof(student));
        free(p);
    }
    */
    int i=1;
    while(stu->next!=NULL)
    {
        printf("第%d个学生的信息:姓名%s  学号%5d 分数%5d\n",i++,stu->name,stu->num,stu->score);
        stu=stu->next;
    }
}

//查找函数
void find(student * stu)
{
    int n;
    printf("按学号查找!\n");
    student *p;
    p=stu->next;
    p=(student *)malloc(sizeof(student));
    printf("查找的学号:");
    scanf("%d",&n);
    for(;p->next;p=p->next)
    {
        if(p->num==n)
        {   
            printf("查找成功\n");
            printf("此学生的信息:姓名%5c  学号%5d 分数%5d\n",p->name,p->num,p->score);
        }
        p->next=(student *)malloc(sizeof(student));

    }
    if(p==NULL)
        printf("无此学生!!!\n");
    free(p);
}

//插入函数
student * insert(student * stu)
{

    student *p,*q;
    p=stu->next;
    p=q=(student *)malloc(sizeof(student));
    printf("输入插入学生的信息 姓名 学号 分数\n");
    scanf("%c%d%d",&q->name,&q->num,&q->score);
    for(;p->next;p=p->next);
    p->next=q;
    p=p->next;
    q->next=NULL;
    return stu;

}

//删除函数
student *del(student * stu)
{
    student *p,*q,*r;
    int n;
    p=stu->next;
    p=q=r=(student *)malloc(sizeof(student));
    printf("输入删除学生的姓名\n");
    scanf("%c%d%d",&n);
    for(;p->next;p=p->next)
    {
        if(p->num==n)
        {   
            printf("此学生的信息:姓名%5c  学号%5d 分数%5d\n",p->name,p->num,p->score);
            r=q->next;
            q->next=r->next;
        }
        q=p;

    }
    if(p==NULL)
        printf("无此学生!!!\n");
    return stu;
}



int main(int argc, char* argv[])
{
    student *stu;
    stu=(student*)malloc(sizeof(student));
    stu->next=NULL;
    int choice,flag=1;
    do{
    
        printf("1:输入 姓名 学号 分数 名次\n 2:输出\n 3:查找\n 4:插入\n 5:删除\n");
        scanf("%d",&choice);
        switch(choice){

        
           case 1:stu=initial(stu);
               break;
        
           case 2:print(stu);
               break;
        
           case 3:find(stu);
               break;
        
           case 4:stu=insert(stu); 
               break;
        
           case 5:stu=del(stu);
               break;
            

        }
        fflush(stdin);
        printf("是否继续 1:是    0:否\n");
        scanf("%d",&flag);
    }while(flag);

    printf("Hello World!\n");
    return 0;
}




本人小菜心血来潮 编了个链表的成绩管理系统
能通过编译
运行时出错了
很想知道 错在哪里
以便以后能够注意
很急,真的很急
我会很感激的

------解决方案--------------------