【问题标题】:I am learning data structures and stuck at implementation of queues using linked-list in c我正在学习数据结构并坚持使用 c 中的链表实现队列
【发布时间】:2020-10-25 06:15:18
【问题描述】:

我已经编写了以下代码来实现队列及其操作(入队)。该程序编译良好,没有错误,但是当输入用于插入(入队操作)时,程序停止工作并显示 a.exe 已停止工作

该程序包含返回节点的create_node()函数、链表初始化函数、队列初始化函数,这两个函数都是void函数,并在链表函数末尾写入插入,然后调用入队函数。 注意:没有显示功能来打印所有元素到队列

我认为初始化函数可能有问题,但我不确定。

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

typedef struct node node;

struct node
{
    int id;
    node *link;
};

typedef struct list
{
    node *head;
    node *tail;
    int number_of_nodes;
} List;

typedef struct queue
{
    List *ptr_list;
} Queue;


static node *create_node(int id,node *link)
{
    node *temp = (node*)malloc(sizeof(node));
    temp->id=id;
    temp->link=link;
    return temp;
    
}
void list_initialize(List *ptr_list)
{
    ptr_list  = (List*)malloc(sizeof(List));
    ptr_list->head=ptr_list->tail=NULL;
    ptr_list->number_of_nodes = 0;
}

void list_insert_rear(List *ptr_list, int id)
{L
    node *temp = create_node(id,NULL);
    if(ptr_list->tail==NULL)
    {
        ptr_list->head=ptr_list->tail=NULL;
        ptr_list->number_of_nodes++;
    }
    else
    {
        ptr_list->tail->link=temp;
        ptr_list->tail=temp;
        ptr_list->number_of_nodes++;
    }
}
void queue_initialize(Queue *queue_list)
{
    queue_list = (Queue*)malloc(sizeof(Queue));
    list_initialize(queue_list->ptr_list);
}
void queue_enqueue(Queue *ptr, int id)
{
    list_insert_rear(ptr->ptr_list,id); 
}
int main()
{
    Queue queue;
    queue_initialize(&queue);
    int choice, id, t;
    int loop = 1;
    while (loop)
    {
        scanf("%d", &choice);
        switch (choice)
        {
        case 0:
            scanf("%d", &id);
            queue_enqueue(&queue, id);
            break;
        default:
             loop =0;
             break;
        }
     }
}



【问题讨论】:

  • 您尝试了哪些测试来尝试了解问题所在?也尽量不要使用来自用户 (scanf) 的输入进行测试,因为您希望在整个测试中获得可重复且一致的结果
  • 提示:仔细看list_initialize
  • 阅读链接的帖子,然后将其应用于list_initialize
  • @1201ProgramAlarm 你能说一下那部分有什么问题吗。

标签: c


【解决方案1】:

这是我实际遇到过几次的问题,而且很难发现。在list_initialize 中,您应该使用List **ptr_list

在这个函数的第一行,你正在改变指针,但只是在这个变量的范围内,所以你放入的指针实际上不再指向数据了,这可以通过将它设置为来解决指向指针的指针。 (这有点难以解释)

该功能将是(未测试):

void list_initialize(List **ptr_list)
{
    List *ptr_listnew;
    ptr_listnew  = (List*)malloc(sizeof(List));
    ptr_listnew->head=ptr_listnew->tail=NULL;
    ptr_listnew->number_of_nodes = 0;
    *ptr_list = ptr_listnew;
}

queue_initialize 也是这种情况,需要进行相同的修复。

【讨论】:

    【解决方案2】:

    您混淆/组合了结构分配和结构初始化,因此您的函数都做得不好。 (见我的顶级 cmets)。结果,您的结构指针未正确初始化,并且您得到 UB(未定义的行为),很可能是 SIGSEGV(段错误)。

    虽然一个函数可以同时做这两件事,但将它们分开可以给你一些洞察力。

    旁注: 不要强制转换 malloc 的结果。见:Do I cast the result of malloc?

    这是一个重构版本。原代码标有#if 0,新代码标有#if 1。错误/修复被注释。

    #include <stdlib.h>
    #include <stdio.h>
    
    typedef struct node node;
    
    struct node {
        int id;
        node *link;
    };
    
    typedef struct list {
        node *head;
        node *tail;
        int number_of_nodes;
    } List;
    
    // NOTE/STYLE: use more descriptive names
    typedef struct queue {
    #if 0
        List *ptr_list;
    #else
        List *queue_list;
    #endif
    } Queue;
    
    static node *
    create_node(int id, node *link)
    {
        node *temp = (node *) malloc(sizeof(node));
    
        temp->id = id;
        temp->link = link;
    
        return temp;
    }
    
    void
    list_initialize(List *ptr_list)
    {
    // NOTE/BUG: you are blowing away caller's pointer value
    #if 0
        ptr_list = malloc(sizeof(List));
    #endif
        ptr_list->head = ptr_list->tail = NULL;
        ptr_list->number_of_nodes = 0;
    }
    
    #if 1
    List *
    list_create(void)
    {
        List *ptr_list;
    
        ptr_list = malloc(sizeof(List));
        list_initialize(ptr_list);
    
        return ptr_list;
    }
    #endif
    
    void
    list_insert_rear(List *ptr_list, int id, int time)
    {
        node *temp = create_node(id, NULL);
    
        if (ptr_list->tail == NULL) {
            ptr_list->head = ptr_list->tail = NULL;
            ptr_list->number_of_nodes++;
        }
        else {
            ptr_list->tail->link = temp;
            ptr_list->tail = temp;
            ptr_list->number_of_nodes++;
        }
    }
    
    void
    queue_initialize(Queue *queue_list)
    {
    // NOTE/BUG: you are blowing away caller's pointer value
    #if 0
        queue_list = malloc(sizeof(Queue));
    #endif
        queue_list->queue_list = list_create();
    }
    
    #if 1
    Queue *
    queue_create(void)
    {
        Queue *queue_list;
    
        queue_list = malloc(sizeof(Queue));
        queue_initialize(queue_list);
    
        return queue_list;
    }
    #endif
    
    // NOTE/BUG: wrong prototype
    #if 0
    void
    queue_enqueue(Queue *queue, int id)
    #else
    void
    queue_enqueue(Queue *queue, int id, int time)
    #endif
    {
    // NOTE/BUG: not enough arguments for call
    #if 0
        list_insert_rear(queue->queue_list, id);
    #else
        list_insert_rear(queue->queue_list, id, time);
    #endif
    }
    
    int
    main(void)
    {
        Queue queue;
    
        queue_initialize(&queue);
        int choice, id, t;
        int loop = 1;
    
    #if 1
        t = 0;
    #endif
    
        while (loop) {
            scanf("%d", &choice);
            switch (choice) {
            case 0:
                scanf("%d", &id);
                queue_enqueue(&queue, id, t);
                ++t;
                break;
            default:
                loop = 0;
                break;
            }
        }
    
    #if 1
        return 0;
    #endif
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-24
      • 2015-11-03
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 2020-04-17
      • 1970-01-01
      相关资源
      最近更新 更多