【问题标题】:Linked Lists - What can cause an address allocated with malloc to never actually be assigned?链接列表 - 什么会导致使用 malloc 分配的地址实际上从未被分配?
【发布时间】:2020-10-22 23:18:24
【问题描述】:

我正在创建一个链接列表,但在阶梯下方的某个地方我没有正确分配地址以将它们链接在一起。

没有编译时错误,但是当我尝试打印 list.head->next 节点时,我的代码中的错误变得明显。打印结果为00000000的地址。

为什么没有分配list.head->next?

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


struct Node 
{
    int data;
    struct Node* next;
};

struct List 
{
    struct Node* head;
} list;


void insert_node(struct Node *new_node) 
{
    if (list.head == NULL)
    {
        list.head = new_node;
    }

    else 
    {
        struct Node *temp = list.head->next;

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

        temp = new_node;  
    }
}

struct Node* create_node(int data)
{
    static int node_number = 0;

    struct Node * new_node= malloc(sizeof(struct Node));
    new_node->data = data;
    new_node->next = NULL;

    printf("Node inside function %d - address:  %p\n", node_number++, new_node);

    return new_node;
}


int main()
{
    struct Node *a = create_node(11);
    struct Node *b = create_node(12);

    insert_node(a);
    insert_node(b);

    printf("%p\n", list.head->next);
}

【问题讨论】:

  • 您认为应该分配到代码的哪个位置?当您使用调试器对其进行跟踪时,为什么不会发生这种情况?
  • 设置temp = new_node;不会改变列表中任何节点的next成员。
  • 调试器没有告诉我任何我可以亲自解释答案的信息。它编译并运行,这是我困惑的一部分。在insert_node 函数中,while 循环继续,直到找到new_node 的可用插槽。如果list.head-&gt;next 可用,则循环中断并将new_node 分配给该点。我做了两个插入实例,所以list.head 由第一个插入分配,但现在list.head-&gt;next 是下一个可用插槽未正确分配。

标签: c data-structures memory-management linked-list singly-linked-list


【解决方案1】:

在 else 语句中的函数 insert_node 内

else {
        struct Node *temp = list.head->next;

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

        temp = new_node;  
    }

没有连接到列表的局部变量temp被改变了。

你需要写

else {
        struct Node *temp = list.head;

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

        temp->next = new_node;  
    }

请注意,让函数依赖于全局变量list 是一个坏主意。在这种情况下,该函数无法处理其他列表。因此,对于每个列表,例如在程序中使用两个列表时,您需要编写一个单独的函数复制代码。

函数至少可以如下定义。

void insert_node( struct List *list, struct Node *new_node ) 
{
    struct Node **current = &list->head;

    while ( *current != NULL ) current = &( *current )->next;

    *current = new_node;
}

struct Node * create_node( int data )
{
    static unsigned int node_number = 0;

    struct Node *new_node = malloc( sizeof( struct Node ) );

    if ( new_node != NULL )
    {
        new_node->data = data;
        new_node->next = NULL;

        printf("Node inside function %u - address:  %p\n", node_number++, ( void * )new_node);
    }

    return new_node;
}

【讨论】:

    【解决方案2】:

    在 else 部分,您将列表迭代到其末尾并为您的 temp 分配新值, 它没有任何影响,因为 temp 是您的局部变量,因此您应该迭代到最后一个之前的一个,并将 value 设置为 temp->next;

    #include <stdlib.h>
    #include <stdio.h>
    
    
    struct Node 
    {
        int data;
        struct Node* next;
    };
    
    struct List 
    {
        struct Node* head;
    } list;
    
    
    void insert_node(struct Node *new_node) 
    {
        if (list.head == NULL)
        {
            list.head = new_node;
        }
    
        else 
        {
            struct Node *temp = list.head;
    
            while (temp->next != NULL)
            {
                temp = temp->next;
            }
    
            temp->next = new_node;
        }
    }
    
    struct Node* create_node(int data)
    {
        static int node_number = 0;
    
        struct Node * new_node= malloc(sizeof(struct Node));
        new_node->data = data;
        new_node->next = NULL;
    
        printf("Node inside function %d - address:  %p\n", node_number++, new_node);
    
        return new_node;
    }
    
    
    int main()
    {
        struct Node *a = create_node(11);
        struct Node *b = create_node(12);
    
        insert_node(a);
        insert_node(b);
    
        printf("%p\n", list.head->next);
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-30
      • 1970-01-01
      • 2014-07-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多