能帮我看看错哪吗,一旦在主函数调用insert函数就出错

现在银行都有排队叫号系统,如果你到银行去办理业务,首先取得一个顺序号,并告诉你前面有多少人在等待。
现在请你设计、并实现该系统。
客户信息包括:取号的号码、客户银行卡号码、客户类型(包括普通客户和vip客户,分别用Ordinary和VIP表示)。
本题要求实现以下功能:
(1)客户进入银行并取号,该功能对应的命令为INnumbertype,number表示客户银行卡号码,type表示客户类型。
(2)在上一题基础上,按取号顺序列出当前未办理业务的客户信息,该功能对应的命令为LIST。
(3)退出系统,该功能对应的命令为QUIT。
三、输入说明:
输入有多行,每行表示一种操作。
本题实现的操作有:
INguestnumberguesttype
其中IN表示入队,guestnumber表示客户银行卡号码,guesttype有两种取值,分别为Ordinary和VIP,表示普通客户与VIP客户。
LIST
按取号的顺序输出队列中所有排队的客户信息。
QUIT
退出银行排队系统
请注意:输入的数据中,只有最后一个命令是QUIT命令。
四、输出说明:
输出有多行,对不同的命令给出不同的输出。
以下是具体的输出说明:
IN客户银行卡号码
客户类型
该命令首先在单独的一行中输出"IN:",然后再输出客户信息。
客户信息包括客户编号客户银行卡号码
客户类型该客户前面的客户数。客户编号由系统在客户取号的时候给定,从1开始顺序编号。
客户类型分为Ordinary和VIP。数据之间用一个空格分开。
请注意:
第一个客户入队后,则该用户的顺序号为1,前面有0个客户等待;
第二个客户入队后,则该用户的顺序号为2,前面有1个客户等待。
以此类推。
LIST
该命令首先在单独的一行中输出"LIST:",后面有若干行按客户取号的顺序输出,每一行输出一个客户的信息,每行的输出格式为
客户编号客户类型该客户前面的客户数
QUIT
在单独的一行中显示"GOODBYE!"后结束程序。
五、输入样列:
IN1000001Ordinary
IN2000003VIP
IN2000009VIP
LIST
QUIT
六、输出样列:
IN:11000001Ordinary0
IN:22000003VIP1
IN:32000009VIP2
LIST:
11000001Ordinary0
22000003VIP1
32000009VIP2
GOODBYE!

#include<bits/stdc++.h>
using namespace std;
int n=0;
typedef struct Student{
    int k;
    int wait;
    char id[20];
    char type[20];
    struct Student* next;
}Student;
Student* createList()
{
    Student *L;
    L=(Student *)malloc(sizeof(Student));
    L->next=NULL;
    return L;
}
void inputSingle(Student *s,int n){
    cin>>s->id>>s->type;
    n++;
    s->k=n;
    s->wait=n-1;
}
void outputSingle(Student *s){
    cout<<s->k<<" "<<s->id<<" "<<s->type<<" "<<s->wait<<"\n";
}
void insertTail(Student *L,Student *s)
{
    Student *pre,*p;
    pre=L;
    p=L->next;
    while(p!=NULL){
        pre=p;
        p=p->next;
    }
    s->next=pre->next;
    pre->next=s;
}
void outputList(Student *L){
    Student *p;
    p=L->next;
    while(p!=NULL){
        outputSingle(p);
        p=p->next;
    }
}
int main()
{
    int n=0;
    Student *L,*s;
    string order;
    while(1){
        cin>>order;
        if(order=="IN"){
            printf("IN:");
            s=(Student *)malloc(sizeof(Student));
            inputSingle(s,n);
            outputSingle(s);
            insertTail(L,s);
        }
        if(order=="LIST"){
            printf("LIST:\n");
            outputList(L);
        }
        else if(order=="QUIT"){
            puts("GOOD BYE!");
            break;
        }
    }
    return 0;
}

修改处见注释,供参考:

//#include<bits/stdc++.h>
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int n=0;
typedef struct Student{
    int   k;
    int   wait;
    char  id[20];
    char  type[20];
    struct Student* next;
}Student;
Student* createList()
{
    Student *L;
    L=(Student *)malloc(sizeof(Student));
    L->next=NULL;
    return L;
}
void inputSingle(Student *s){   //,int n){ //修改
    cin>>s->id>>s->type;
    n++;
    s->k=n;
    s->wait=n-1;
}
void outputSingle(Student *s){
    cout<<s->k<<" "<<s->id<<" "<<s->type<<" "<<s->wait<<"\n";
}
void insertTail(Student *L,Student *s)
{
    Student *pre,*p;
    pre=L;
    p=L->next;
    while(p!=NULL){
        pre=p;
        p=p->next;
    }
    s->next=pre->next;
    pre->next=s;
}
void outputList(Student *L){
    Student *p;
    p=L->next;
    while(p!=NULL){
        outputSingle(p);
        p=p->next;
    }
}
int main()
{
    //int n=0;       //修改
    Student *L,*s;
    L = createList();//修改
    string order;
    while(1){
        cin>>order;
        if(order=="IN"){
            printf("IN:");
            s=(Student *)malloc(sizeof(Student));
            inputSingle(s);   //,n); //修改
            outputSingle(s);
            insertTail(L,s);
        }
        else if(order=="LIST"){ //修改
            printf("LIST:\n");
            outputList(L);
        }
        else if(order=="QUIT"){
            puts("GOOD BYE!");
            break;
        }
    }
    return 0;
}

你的L 没有分配内存,执行 insertTail(L,s);的时候,L->next就是非法访问