C - 指针和前置单链表

时间:2017-07-21 20:30:17

标签: c pointers

我试图理解前置后面的指针逻辑。

我声明了一个结构如下:

typedef struct myList{
    int info;
    struct myList *link; //self referential structure;
} Node;

对于堆内存段中的内存分配,我使用以下函数:

Node *getNode(){
    return ((Node *)malloc(sizeof(Node)));
}

在main函数中,我为第一个节点分配内存,我将其链接指定为NULL,将其值指定为2.

Node *head = getNode();
head -> link = NULL;
head -> info = 2;

然后是前置函数:

void prepend(Node **headPointer, int value) {
    Node *new_node;
    new_node         = getNode();
    new_node -> info = value;
    new_node -> link = *headPointer;
    *headPointer     = new_node;
}

我正在使用以下函数调用:

prepend(&head, 5)

如您所见,我正在使用指向指针的指针。我将head的地址存储在headPointer中。我创建new_node并为其分配内存。我分配了它的信息字段,然后链接字段得到解除引用的headPointer,它是存储在head中的值,而head又是堆段中内存块的地址。

所以,我基本上将new_node链接到head,对吧?对我来说,现在是令人困惑的部分。取消引用的headPointer是Heap段中头部指向的内存块,它获取存储在new_node中的值,这是Heap段中的另一个地址,我猜。然后,new_node和headPointer都超出了范围。 (?)

这一切如何加起来?是否有更简单的方法来描述情况或实施前置?

1 个答案:

答案 0 :(得分:2)

  

然后,new_node和headPointer都超出了范围。 (?)

prepend() newnode结束时超出了范围但没有分配的内存,因为它是在堆上分配的。如果它类似int a,那么在结束时prepend()a超出范围并在引用a之后将是未定义的行为。请阅读thisthis以了解堆。

此外,由于您将列表的头部作为指针传递给指针,当您更改headPointer指向prepend()内部的内容时,它会反映在函数外部,因此您仍然可以指向头部列表。

|2|-->NULL
 ^ 
 |
head

致电prepend()

1)  |5|-->  |2|-->NULL
             ^ 
             |
           head  

2)  |5|---->   |2|--->NULL
     ^
     |
    head

还记得有一些方法可以访问堆分配的内存以释放它。如果你没有任何方法指向分配在堆上的内存,那么你就会留下内存泄漏。