【问题标题】:Linked list in c adding to beginning of the listc中的链表添加到列表的开头
【发布时间】:2020-06-23 19:19:30
【问题描述】:

我正在尝试创建一个简单的程序来向链表添加值。 代码确实编译没有错误。 尝试执行文件时出现分段错误。 我尝试使用 printf 语句进行调试,但在任何地方都没有得到任何输出。 有人可以指出我做错了什么。

typedef 结构在单独的 .h 文件中,包含文件也在单独的 .h 文件中

typedef struct      s_list
    {
        struct s_list   *next;
        void            *data;
    }                   t_list;


void    list_push_front(t_list **begin_list, void *data)
{
    t_list *l;

    l = (t_list*)malloc(sizeof(t_list));
    if(l == NULL){
        printf("No allocation");
    }
    printf("%s\n", l->data);
    l->data = data;
    l->next = *begin_list;
    *begin_list = l;
    printf("%s\n", l->data);

}

int     main(void)
{
    t_list *k;
    k = (t_list*)malloc(sizeof(t_list));
    if(k == NULL){
        printf("No allocation");
    }
    printf("allocation");
    char s[] = "Woow!";
    k->data = "Hello";
    k->next->data = NULL;
//  k->next->next->data = NULL;
    list_push_front(&k, s);
    return(0);
}

【问题讨论】:

  • k->next 未初始化时,为什么要寻址 k->next->data?

标签: c struct linked-list undefined-behavior singly-linked-list


【解决方案1】:

在printf 通话中

l = (t_list*)malloc(sizeof(t_list));
if(l == NULL){
    printf("No allocation");
}
printf("%s\n", l->data);

您正在尝试输出指针l->data 指向的未初始化内存。因此该函数调用未定义的行为。删除这个printf 的调用。这没有意义。

也在主要的这个声明中

k->next->data = NULL;

不正确,还会调用未定义的行为。看来你的意思

k->next = NULL;

【讨论】:

    【解决方案2】:

    一般来说,始终使用-Wall -Werror 标志进行编译并经常运行您的代码(每隔几行)。这应该有助于避免这里的很多问题。使用valgrind、asan 或gdb 来检测和诊断类似本程序中的内存问题。

    • k->next->data = NULL; 是非法的,因为 k->next 未初始化。
    • printf("%s\n", l->data);,同样的问题。您必须在使用前初始化一个值。
    • 函数不应产生像打印这样的副作用。临时调试是可以的,但除此之外,它会导致嘈杂的程序和基本上无法使用的功能。如果您需要错误,请打印到 stderr 并退出,或使用枚举或 NULL 等返回值来指示错误。
    • 始终free 分配内存。
    • No need to cast the result of malloc。
    • 使用一致的缩进和格式。

    可能的重写:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct ListNode {
        struct ListNode *next;
        void *data;
    } ListNode;
    
    ListNode *list_create(void *data) {
        ListNode *node = malloc(sizeof(*node));
    
        if (!node) {
            fprintf(stderr, "%s %d: malloc failed\n", __FILE__, __LINE__);
            exit(1);
        }
    
        node->data = data;
        node->next = NULL;
        return node;
    }
    
    void list_push_front(ListNode **head, void *data) {
        ListNode *node = list_create(data);
        node->next = *head;
        *head = node;
    }
    
    void list_free(ListNode *head) {
        while (head) {
            ListNode *dead = head;
            head = head->next;
            free(dead);
        }
    }
    
    int main(void) {
        ListNode *list = list_create("a");
        list_push_front(&list, "b");
        list_push_front(&list, "c");
    
        for (ListNode *curr = list; curr; curr = curr->next) {
            printf("%s\n", (char *)curr->data);
        }
    
        list_free(list);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-16
      • 2021-06-28
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多