VS2019运行单链表的插入和删除操作时引发异常?

代码运行时具体异常如下:
图片说明图片说明!图片说明图片说明
具体代码如下

/*======开发环境:Windows10,Visual Studio Community 2019 版本:16.5.4===========*/
/*=================头文件=====================*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>


typedef struct node //定义结点
{
    char data[10];  //结点的数据域为字符串
    struct node* next;  //结点的指针域
}ListNode;
typedef ListNode* LinkList; //自定义LinkList单链表类型


/*=====================函数声明=========================*/
LinkList CreatListR1(); //用头插入法建立带头结点的函数
ListNode* LocateNode(LinkList head, char* key); //函数,按值查找结点
void insertlist(LinkList head, int i, char key);    //函数,插入结点
void deletelist(LinkList head, char* key);  //函数,删除指定值的结点
void printlist(LinkList head);  //函数,打印链表中的所有值
void deleteall(LinkList head);  //函数,删除整个链表


/*====================主函数=======================*/
int main()
{
    char* ch;
    char num[4];
    char b[8];
    ch = &b[0];
    int i;
    LinkList head;
    head = CreatListR1();   //用头插入法建立单链表,返回头指针
    printlist(head);
    printf("输入y或n选择是否插入结点。\n");
    scanf("%s", num);
    if (strcmp(num, "y") == 0 || strcmp(num, "Y") == 0)
    {
        printf("请输入要插入的字符串:");
        scanf("%s", ch);
        printf("\n请输入要插入的位置:");
        scanf("%d", &i);
        insertlist(head, i, ch);
        printlist(head);
    }
    printf("输入y或n选择是否删除结点。\n");
    scanf("%s", num);
    if (strcmp(num, "y") == 0 || strcmp(num, "Y") == 0)
    {
        printf("请输入要删除的字符串:");
        scanf("%s", ch);
        deletelist(head, ch);
        printlist(head);
    }
    deleteall(head);
    system("pause");
}


/*============用头插入法建立带头结点的函数==============*/
/*@param    void*/
/*@return   返回头指针*/
/*@note     让用户自己输入字符串,创建单链表*/
LinkList CreatListR1(void)
{
    char* ch;
    char a[8];
    ch = &a[0];
    LinkList head = (LinkList)malloc(sizeof(ListNode)); //创建头结点
    ListNode* s, * r, * pp;
    r = head;
    r->next = NULL; //初始为空链表
    printf("输入“#”代表输入结束。\n");
    printf("请输入不重复的字符串:\n");
    scanf("%s", ch);
    while (strcmp(ch, "#") != 0)
    {
        pp = LocateNode(head, ch);  //查找是否输入的字符串已经存在
        if (pp == NULL)
        {
            s = (ListNode*)malloc(sizeof(ListNode));    //创建新的结点
            strcpy(s->data, ch);
            s->next = r->next;
            r->next = s;    //将新结点插入表中
        }
        else
        {
            printf("输入了重复的字符串。\n");
        }
        printf("输入“#”代表输入结束。\n");
        printf("请输入不重复的字符串:\n");
        scanf("%s", ch);
    }
    return head;    //返回头指针
}


/*============按值查找结点,找到则返回结点位置,否则返回NULL==================*/
/*@param    LinkList head:要查找的单链表的头指针*/
/*@param    char* key:要查找的字符串*/
/*@return   若未查找到,返回NULL,如果查找到,返回字符串的结点位置*/
/*@note     按值查找结点*/
ListNode* LocateNode(LinkList head, char* key)
{
    ListNode* p = head->next;   //开始结点比较
    while (p && (p->data != key))   //直到p=NULL或者p->data==key为止
        p = p->next;    //扫描下一个结点
    return p;   //若p=NULL则查找失败,返回NULL,否则p指向查找的字符串的结点位置
}


/*=================向指定结点插入指定值===================*/
/*@param    LinkList head:要插入指定值的单链表的头指针*/
/*@param    int i:要插入字符串的位置*/
/*@param    char* key:要删除的字符串*/
/*@return   void*/
/*@note     在指定位置插入指定字符串*/
void insertlist(LinkList head, int i, char* key)
{
    ListNode* p, * t, * pp;
    int j;
    p = head;
    j = 0;
    pp = LocateNode(head, key); //查找是否输入的字符串已存在
    if (pp == NULL)
    {
        while (p != NULL && j < i - 1)  //寻找第i-1个结点
        {
            p = p->next;
            j++;
        }
        if (j != i - 1)
        {
            printf("错误的插入位置。\n");
            return;
        }
        t = (ListNode*)malloc(sizeof(ListNode));
        strcpy(t->data, key);   //将字符串s赋值给数据域
        t->next = p->next;
        p->next = t;
    }
    else
        printf("输入的字符串已存在。\n");
}


/*===================删除指定值的结点=======================*/
/*@param    LinkList head:要删除指定值的单链表的头指针*/
/*@param    char* key:要删除的字符串*/
/*@return   void*/
/*@note     删除指定字符串的结点*/
void deletelist(LinkList head, char* key)
{
    ListNode* p, * r, * q = head;
    p = LocateNode(head, key);  //按照key值查找结点
    if (p = NULL)   //若没有找到key值,退出
    {
        printf("输入的字符串不存在。\n");
        exit(0);
    }
    while (q->next != p)    //p为要删除的结点,q为p的前结点
        q = q->next;
    r = q->next;
    q->next = r->next;  //将r的指针域赋值给q的指针域
    free(r);    //释放结点
}


/*==============打印单链表=============*/
/*@param    LinkList head:要打印的单链表的头指针*/
/*@return   void*/
/*@note     打印单链表*/
void printlist(LinkList head)
{
    ListNode* p = head->next;   //从开始结点打印
    while (p)
    {
        printf("%s,  ", p->data);
        p = p->next;
    }
    printf("\n");
}


/*==================删除整个单链表,释放空间=================*/
/*@param    LinkList head:要删除的单链表的头指针*/
/*@return   void*/
/*@note     删除整个单链表*/
void deleteall(LinkList head)
{
    ListNode* p = head, * r;
    while (p->next)
    {
        r = p->next;
        free(p);
        p = r;
    }
    free(p);
}


2个回答

void insertlist(LinkList head, int i, char key); //函数,插入结点
定义时char key 是有*的。少敲了*

fgsdfgsda
fgsdfgsda 谢谢
3 个月之前 回复

r虽然声明了但是没有赋值,所以你r只是一个空指针,也就是说你r没有实际操作的内存空间,使用前必须先给r赋值

fgsdfgsda
fgsdfgsda r = q->next;这句就是给r赋值了吧
3 个月之前 回复
fgsdfgsda
fgsdfgsda 谢谢
3 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐