关于#c语言#的问题:但我的输出是运行错误,而且是段错误(可能是指针的地址问题,但我一直找不到哪个指针错了)

我用C语言写了一个银行排队系统,用了链队列。但我的输出是运行错误,而且是段错误(可能是指针的地址问题,但我一直找不到哪个指针错了)。这个问题困惑了我好几天了,能帮我看看是哪个错了吗。。

img

img

 输入样列
      OUT
     IN 1000001 Ordinary
      IN 2000003 VIP
      IN 2000009 VIP
      OUT
     OUT
      IN 2000008 VIP
     LIST
     QUIT
 输出样例
      FAILED:
      IN:1 1000001 Ordinary 0
      IN:2 2000003 VIP 1
      IN:32000009 VIP 2
     OUT:1 1000001 Ordinary
      OUT:22000003VIP
      IN:42000008VIP1
      LIST:
     32000009VIP
     42000008VIP
      GOOD BYE!
 #include 
using namespace std;
#define M 30

//创建客户信息数据类型
typedef struct
{
    int num;//取号的号码(客户编号)
    char guestnumber[M];//客户银行卡号码
    char guesttype[M];//客户类型
    int pre;//该客户前的客诉数就是rear-front-1;//因为链表中的元素不是在同一块空间中,所以该方法是不可行的
}ElementType;

//创建包含指针的结构体
typedef struct Node
{
    ElementType data;
    struct Node* next;
}Node;

//队列结构体
typedef struct
{
    Node *front;
    Node *rear;
}LinkQueue;

//创建一个空队列
LinkQueue *createQueue()
{
    LinkQueue *Q = (LinkQueue *)malloc(sizeof(LinkQueue));
    //创建头结点
    Q->front = (Node *)malloc(sizeof(Node));
//    printf("create headNode id: %p\n",Q->front);
    Q->front->next = NULL;
    Q->rear = Q->front;
    Q->front->data.num = 0;
    Q->rear->data.num = Q->front->data.num;
    Q->front->data.pre = 0;
    Q->rear->data.pre = Q->front->data.pre;

    return Q;
}

//判空
int empty(LinkQueue *Q)
{
    if(Q->front==Q->rear)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

//入队
int push(LinkQueue *Q, ElementType x)
{
    Node *p = (Node *)malloc(sizeof(Node));
//    printf("createNode id: %p\n",p);
    if(p==NULL)
    {
        return 0;
    }
    else
    {
    p->next = NULL;
    p->data = x;
    
    Q->rear->next = p;
    Q->rear = p;
    return 1;
    }
}

//出队
/*int pop(LinkQueue *Q)
{
    if(empty(Q))
    {
        return 0;
    }
    else 
    {
        Node *temp = Q->front->next;
        Q->front->next = temp->next;
        free(temp);
        return 1;
    }
}*/

//find输出队列长度
int find(LinkQueue *Q)
{
    int k = 0;
    Node *temp = Q->front;
    while(temp->next!=NULL)
    {
        k++;
        temp = temp->next;
    }
    temp = NULL;
    return k;
}


//VIP插队


//IN
void IN(LinkQueue *Q, int num)
{
    //读取数据
    ElementType p;
    scanf("%s %s",p.guestnumber,p.guesttype);
    p.num = num;
    p.pre = find(Q);
    push(Q, p);
    //将节点连入队列
    
    
    printf("IN:");
    printf("%d %s %s %d\n",p.num,p.guestnumber,p.guesttype,p.pre);    
    
}

//LIST//遍历队列元素
void LIST(LinkQueue *Q)
{
    printf("LIST:\n");
    //通过临时指针遍历队列
    Node *temp = Q->front->next;
    for(temp; temp!=NULL; temp=temp->next)
    {
        printf("%d %s %s\n",temp->data.num,temp->data.guestnumber,temp->data.guesttype);
    }
}

//OUT
void OUT(LinkQueue *Q)
{
    //空队列则返回0
    if(empty(Q))
    {
        printf("FAILED:\n");
    }
    else//队头出列
    {
        printf("OUT:");
        Node *temp = Q->front->next;
//        printf("head Ndoe id: %p\n",Q->front);
//        printf("first Ndoe id: %p\n",Q->front->next);
        Q->front->next = temp->next;
//        printf("second Node id: %p\n",Q->front->next);
        printf("%d %s %s\n",temp->data.num,temp->data.guestnumber,temp->data.guesttype);
        free(temp);
        temp = NULL;
//        printf("temp id: %p\n",temp);
    }
}

//QUIT
void QUIT(LinkQueue *Q)
{
    printf("GOOD BYE!\n");
    //队列的销毁
    while(Q->front)
    {
        Q->rear = Q->front->next;
//        printf("tail Node id: %p\n",Q->rear);
//        printf("will be DELETE Node id: %p\n",Q->front);
        free(Q->front);
        Q->front = Q->rear;
    }
//    free(Q->rear);
    free(Q);
    Q = NULL;
    exit(0);//退出程序
}


int main()
{
    int a = 0;//记录客户编号
    LinkQueue * Q = createQueue();
    char cmd[M];
    while(1)
    {
        scanf("%s",cmd);
        switch(cmd[0])
        {
            case'I':
            {
                a++;
                IN(Q,a);
                break;
            }
            case'L':
                LIST(Q);
                break;
            case'O':
                OUT(Q);
                break;
            case'Q':
                QUIT(Q);
                break;                    
        }
    }    
    return 0;
}

输出前你执行了哪些操作啊,增删改查都执行了哪几个?

参考GPT和自己的思路,修改后的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define M 30

//创建客户信息数据类型
typedef struct
{
    int num; // 取号的号码(客户编号)
    char guestnumber[M]; // 客户银行卡号码
    char guesttype[M]; // 客户类型
    int pre; // 该客户前的客诉数就是rear-front-1;//因为链表中的元素不是在同一块空间中,所以该方法是不可行的
} ElementType;

//创建包含指针的结构体
typedef struct Node
{
    ElementType data;
    struct Node* next;
} Node;

//队列结构体
typedef struct
{
    Node *front;
    Node *rear;
} LinkQueue;

//创建一个空队列
LinkQueue* createQueue()
{
    LinkQueue* Q = (LinkQueue*)malloc(sizeof(LinkQueue));
    //创建头结点
    Q->front = (Node*)malloc(sizeof(Node));
    Q->front->next = NULL;
    Q->rear = Q->front;
    Q->front->data.num = 0;
    Q->rear->data.num = Q->front->data.num;
    Q->front->data.pre = 0;
    Q->rear->data.pre = Q->front->data.pre;

    return Q;
}

//判空
int empty(LinkQueue* Q)
{
    if (Q->front == Q->rear)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

//入队
int push(LinkQueue* Q, ElementType x)
{
    Node* p = (Node*)malloc(sizeof(Node));
    if (p == NULL)
    {
        return 0;
    }
    else
    {
        p->next = NULL;
        p->data = x;

        Q->rear->next = p;
        Q->rear = p;
        return 1;
    }
}

//出队
int pop(LinkQueue* Q)
{
    if (empty(Q))
    {
        return 0;
    }
    else
    {
        Node* temp = Q->front->next;
        Q->front->next = temp->next;
        free(temp);
        return 1;
    }
}

//find输出队列长度
int find(LinkQueue* Q)
{
    int k = 0;
    Node* temp = Q->front;
    while (temp->next != NULL)
    {
        k++;
        temp = temp->next;
    }
    temp = NULL;
    return k;
}

//VIP插队

//IN
void IN(LinkQueue* Q, int num)
{
    //读取数据
    ElementType p;
    scanf("%s %s", p.guestnumber, p.guesttype);
    p.num = num;
    p.pre = find(Q);
    push(Q, p);
    //将节点连入队列

    printf("IN:");
    printf("%d %s %s %d\n", p.num, p.guestnumber, p.guesttype, p.pre);

}

//遍历队列
void traverse(LinkQueue* Q)
{
QueuePtr p = Q->front->next;
while (p)
{
printf("%d %s %s %d\n", p->data.num, p->data.guestnumber, p->data.guesttype, p->data.pre);
p = p->next;
}
}

//查找当前队列中最后一个节点的位置
int find(LinkQueue* Q)
{
QueuePtr p = Q->front;
int pre = 0;
while (p != Q->rear)
{
pre = p->next->data.num;
p = p->next;
}
return pre;
}

//入队操作
void IN(LinkQueue* Q, int num)
{
//读取数据
ElementType p;
scanf("%s %s", p.guestnumber, p.guesttype);
p.num = num;
p.pre = find(Q);
push(Q, p);
//将节点连入队列
printf("IN:");
printf("%d %s %s %d\n", p.num, p.guestnumber, p.guesttype, p.pre);
}
int main()
{
LinkQueue Q;
InitQueue(&Q);
int n, i;
scanf("%d", &n);

for (i = 1; i <= n; i++)
{
    IN(&Q, i);
}

traverse(&Q);

return 0;
}

其中,ElementType是链队列的节点元素类型,包含嘉宾编号(guestnumber)、嘉宾类型(guesttype)、当前嘉宾的序号(num)以及前一位嘉宾的序号(pre)。