Anonymous 发表于 2023-3-2 13:35:59

单链表3 课后 通讯录程序

本帖最后由 匿名 于 2023-3-2 13:40 编辑

问题:为何释放节点之后会有残留?

预想情况:在 void delCall(struct Call *head) 的情况下,del的head无法与main中的head建立联系,将curr的节点删除之后,打印main中的head链表应该无法输出结果,空或是乱码。



如图,删除的b节点有一部分数据保留了,这是为什么?

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

struct Call
{
    char name;
    char number;
    struct Call *next;
};

void addCall(struct Call **head);
void findCall(struct Call *head);
void changeCall(struct Call *head);
void delCall(struct Call *head);
void printCall(struct Call *head);
void freeCall(struct Call *head);

void addCall(struct Call **head)
{
    struct Call *new = NULL;

    new = (struct Call *) malloc(sizeof(struct Call));

    if(new == NULL)
    {
      exit(1);
    }

    printf("请输入姓名:");
    scanf("%s",new->name);
    printf("请输入电话:");
    scanf("%s",new->number);

    if(*head != NULL)
    {
      new->next = *head;
      *head = new;
    }
    else
    {
      *head = new;
      new->next = NULL;
    }
}

void findCall(struct Call *head)
{
    char name;
    struct Call *temp = head;

    printf("请输入联系人:");
    scanf("%s",name);

    do
    {
      if(!strcmp(temp->name,name))
      {
            printf("联系人:%s\n",temp->name);
            printf("电话:%s\n",temp->number);
      }
    }
    while((temp = temp->next) != NULL);

    if(temp == NULL)
    {
      printf("抱歉,没有此人的联系方式\n");
    }
}

void changeCall(struct Call *head)
{
    char name;
    struct Call *temp = head;

    printf("请输入联系人:");
    scanf("%s",name);

    do
    {
      if(!strcmp(temp->name,name))
      {
            printf("请输入新的联系电话:");
            scanf("%s",temp->number);
            break;
      }
    }
    while((temp = temp->next) != NULL);                       

    if(temp == NULL)                                                       
    {
      printf("抱歉,没有此人的联系方式\n");
    }
}

void delCall(struct Call *head)
{
    char name;
    struct Call *current = head;
    struct Call *previous = NULL;

    printf("请输入联系人:");
    scanf("%s",name);

    while(current != NULL)
    {
      if(!strcmp(current->name,name))
      {
            break;
      }

      previous = current;
      current = current->next;
    }

    if(current == NULL)
    {
      printf("抱歉,没有此人的联系方式\n");
    }
    else
    {
      if(previous == NULL)
      {
            head = current->next;
      }
      else
      {
            previous->next = current->next;
      }
      free(current);
    }
}

void printCall(struct Call *head)
{
    while(head != NULL)
    {
      printf("联系人:%s\n",head->name);
      printf("电话:%s\n",head->number);
      head = head->next;
    }
}

void freeCall(struct Call *head)
{
    struct Call *temp = head;

    while (head != NULL)
    {
      temp = head;
      head = head->next;
      free(temp);
    }
}

int main(void)
{
    int input;
    struct Call *head = NULL;

    printf("\n| 欢迎使用通讯录管理程序 |\n\n");
    printf("|---1.插入新的联系人---|\n");
    printf("|---2.查找已有通讯录---|\n");
    printf("|---3.更改已有通讯录---|\n");
    printf("|---4.删除已有通讯录---|\n");
    printf("|---5.显示当前通讯录---|\n");
    printf("|---6.退出通讯录程序---|\n");
    printf("|- Powered by FishC.com -|\n\n");

    while(1)
    {
      printf("请输入指令代码:");
      scanf("%d",&input);

      switch(input)
      {
            case 1: addCall(&head); putchar('\n'); break;
            case 2: findCall(head); putchar('\n'); break;
            case 3: changeCall(head); putchar('\n'); break;
            case 4: delCall(head); putchar('\n'); break;               //疑问为什么删除节点,只有名字丢失
            case 5: printCall(head); putchar('\n'); break;
            case 6: freeCall(head); printf("感谢使用!\n"); goto END;      
      }
    }

    END:
    return 0;
}

两手空空儿 发表于 2023-3-2 15:20:52

case 4: delCall(head); putchar('\n'); break;               //疑问为什么删除节点,只有名字丢失

if(previous == NULL)
      {
            head = current->next;   这里的head是一个局部变量,链表头结点的位置并没有改变
      }


case 4:这里应该传head的地址 delCall( &head)   子程序做相应更改

sfqxx 发表于 2023-3-2 17:54:45

领个鱼币{:10_256:}

Aixer 发表于 2023-3-2 20:07:11

两手空空儿 发表于 2023-3-2 15:20


嗯嗯,我更想问的问题是为什么在头节点位置没有改变的情况下,本被释放的数据还会有保留,并且链表被打印了下来

两手空空儿 发表于 2023-3-3 09:30:28

Aixer 发表于 2023-3-2 20:07
嗯嗯,我更想问的问题是为什么在头节点位置没有改变的情况下,本被释放的数据还会有保留,并且链表被打印 ...

free是告诉操作系统这块内存空闲了,可以被再分配,但是里面存放的内容并没有被擦除,被再次使用之前,它的内容保持不变

Aixer 发表于 2023-3-3 15:27:41

两手空空儿 发表于 2023-3-3 09:30
free是告诉操作系统这块内存空闲了,可以被再分配,但是里面存放的内容并没有被擦除,被再次使用之前,它 ...

谢谢
页: [1]
查看完整版本: 单链表3 课后 通讯录程序