链接列表内存

时间:2016-04-17 01:26:01

标签: c memory-management linked-list

当在下面的交叉函数中进行第一次push调用时,tail-> next的值为NULL。我的理解是& tail-> next然后指向堆栈上的虚拟对象的最后4个字节,它保存指向next的指针。现在当push函数内部更改head_ref时,我们是否更改了存储在虚拟对象的下一个变量中的地址?所以在我看来,dummy总是指向列表的最后一个元素,即使这在执行时正确输出了列表的头部。有人可以解释每次推送呼叫在内存中发生的情况吗?感谢。

此问题取自here

struct node* sortedIntersect(struct node* a, struct node* b)
{
    struct node dummy;
    struct node* tail = &dummy;
    dummy.next = NULL;

    while (a != NULL && b != NULL)
    {
        if (a->data == b->data)
        {
            push((&tail->next), a->data);
            tail = tail->next;
            a = a->next;
            b = b->next;
        }
        else if (a->data < b->data) /* advance the smaller list */
            a = a->next;
        else
            b = b->next;
    }
    return(dummy.next);
}

void push(struct node** head_ref, int new_data)
{
    struct node* new_node =
        (struct node*) malloc(sizeof(struct node));

    new_node->data = new_data;

    /* link the old list off the new node */
    new_node->next = (*head_ref);

    /* move the head to point to the new node */
    (*head_ref) = new_node;
}

2 个答案:

答案 0 :(得分:0)

push的第一次调用确实会改变虚拟对象的下一个指针,但随后tail会提前指向刚按下的元素(tail = tail->next)。因此,下一个push对该节点的next进行操作,而不是虚拟节点。

答案 1 :(得分:0)

假人开始像这样:

______     ______
|dummy| -> |NULL|
| 0   |    |    |
-------    ------

在第一次致电push(&tail->next, a->data)之后,我将假设a->data5,这将使您失望(请记住tail指向{dummy 1}}此时):

 ______    _________      _____
|dummy| -> |new_node| -> |NULL|
|  0  |    |   5    |    |    |
 -----     ---------     ------

然后我们致电tail = tail->next;,这会导致tail指向new_node,这就是为什么我们再次致电push(&tail->next, a->data)new_node 2号将插入旧new_nodeNULL

之间

最后,我们调用return dummy->next,它将返回链接列表,其中最近添加的节点位于第一位。虚拟本身将被删除,因为它是在堆栈上分配的。

push函数变得更加清晰,如果我们这样写的话:

void push(struct node** head_ref, int new_data)
{
    struct node* new_node =
        (struct node*) malloc(sizeof(struct node));

    new_node->data = new_data;

    /* save old head */
    struct node* old_head = *head_ref;

    /* move the head to point to the new node */
    *head_ref = new_node;

    /* link the old list off the new node */
    new_node->next = old_head;
}