真不敢相信我会问这个.

我写了一个简单的链表,似乎有一个奇怪的错误我找不到.请帮帮我.

我在前面加1,然后加2.然后我删除一个值为2的 node ,它是头.

就在delete(head, 2);个回报之前,我有head->data == 1个.但在Main中的呼叫之后,我得到了head->value == 0. 代码如下:

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

typedef struct linked_list
{
    int data;
    struct linked_list *next;
} linked_list_t;

void print_list(linked_list_t *head)
{
    linked_list_t *curr = head;
    printf("LIST: ");
    while (curr)
    {
        printf("%d ", curr->data);
        curr = curr->next;
    }
    printf("\n");
    fflush(stdout);
    
}

linked_list_t *add_to_front(linked_list_t *head, int data) 
{
    linked_list_t *new = malloc(sizeof(linked_list_t));
    if (!new) exit(1);
    new->next = head;
    new->data = data;
    return new;
}

void delete(linked_list_t *head, int data) 
{
    linked_list_t *current = head;
    linked_list_t *previous = NULL;
    // move current to the position of the node to delete
    while (current != NULL && current->data != data) 
    {
        previous = current;
        current = current->next;
    }

    if (current)
    {
        if (previous) 
        {
            // if the node to delete is not head
            previous->next = current->next;
        }
        else
        {
            // if the node to delete is head
            head = current->next;
        }
    }
    free(current);
}

int main()
{
    linked_list_t *head = NULL;
    print_list(head);
    // prints "LIST:"
    head = add_to_front(head, 1);
    head = add_to_front(head, 2);
    print_list(head);
    // prints "LIST: 2 1"
    // head->data = 1 just before delete() exits
    delete(head, 2);
    // head->data = 0 right after delete() exits
    print_list(head);
    // prints "LIST: 0 1" instead of "LIST: 1" 
}

推荐答案

head指针被取消引用时,您的程序在第三次也是最后一次(双关语)调用print_list()时出现分段.head仍然指向上一次调用delete()时空闲的 node .C中的参数是通过值传递的,所以在delete()中,当您这样做时,head = current->next;delete()函数之外没有任何效果.您有两个 Select :

  1. 退回新的head元(见下文)或
  2. 传入**head,这样您就可以更新它

(不固定)以后缀_t结尾的符号是保留的,因此避免使用该后缀.如果是I typedef,则默认使用与struct相同的名称.

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

typedef struct linked_list {
    int data;
    struct linked_list *next;
} linked_list_t;

void print_list(linked_list_t *head) {
    printf("LIST:");
    for(linked_list_t *curr = head; curr; curr = curr->next)
        printf(" %d", curr->data);
    printf("\n");
    fflush(stdout);

}

linked_list_t *add_to_front(linked_list_t *head, int data) {
    linked_list_t *new = malloc(sizeof(linked_list_t));
    if (!new) exit(1);
    new->next = head;
    new->data = data;
    return new;
}

linked_list_t *delete(linked_list_t *head, int data) {
    linked_list_t *current = head;
    linked_list_t *previous = NULL;
    for(; current && current->data != data; current = current->next)
        previous = current;
    if (current) {
        if (previous) {
            previous->next = current->next;
            free(current);
        } else {
            current = current->next;
            free(head);
            head = current;
        }
    }
    return head;
}

int main(void) {
    linked_list_t *head = NULL;
    print_list(head);
    head = add_to_front(head, 1);
    head = add_to_front(head, 2);
    print_list(head);
    head = delete(head, 2);
    print_list(head);
}

和示例运行:

LIST:
LIST: 2 1
LIST: 1

我更喜欢特殊情况的早期回归,所以我会以以下方式结束:

linked_list_t *delete(linked_list_t **head, int data) {
    if(!head)
        return head;
    if(head->data == data) {
        linked_list_t *tmp = head->next;
        free(head);
        return tmp;
    }
    for(linked_list_t *p = head; p->next; p=p->next) {
        if(p->next->data == data) {
            linked_list_t *tmp = p->next->next;
            free(p->next);
            p->next = tmp;
            break; // or not if you want to delete all matching
        }
    }
    return head;
}

C++相关问答推荐

intellisense不工作,甚至已经下载了c/c++扩展

字符数组,字符指针,在一种情况下工作,但在另一种情况下不工作?

我编译了一个新的c程序,并收到以下错误

正在try 将文件/文件夹名从目录 struct 存储到链接列表

为什么内核使用扩展到前后相同的宏定义?

进程已完成,退出代码为138 Clion

如何捕捉只有换行符或空格字符缓冲区的边缘大小写

Vcpkg的配置文件

为 struct 中的数组动态分配内存时出错

C语言中的外部关键字

初始成员、公共初始序列、匿名联合和严格别名如何在C中交互?

条件跳转或移动取决于未初始化值(S)/未初始化值由堆分配创建(Realloc)

Fscanf打印除退出C代码为1的程序外的所有内容

我编写这段代码是为了判断一个数字是质数、阿姆斯特朗还是完全数,但由于某种原因,当我使用大数时,它不会打印出来

哪些C++功能可以在外部C块中使用

WSASocket在哪里定义?

C 程序不显示任何输出,但它接受 CS50 Lab1 的输入问题

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

使用复合文字数组初始化的指针数组

为什么创建局部变量的指针需要过程在堆栈上分配空间?