我试图理解前置背后的指针逻辑。
我声明了一个结构如下:
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 中的值,它又是 Heap 段中内存块的地址。
所以,我基本上将 new_node 链接到 head,对吧?对我来说,现在是令人困惑的部分。取消引用的 headPointer 是堆段中头的指向内存块,它获取存储在 new_node 中的值,我猜这是堆段中的另一个地址。然后,new_node 和 headPointer 都超出范围。 (?)
这一切如何加起来?有没有更简单的方法来描述情况或实现前置?
最佳答案
Then, both new_node and headPointer go out of scope. (?)
在 prepend()
的末尾,newnode
超出了范围但没有分配内存,因为它是在堆上分配的。如果它像 int a
,然后在 prepend()
结束时,a
超出范围并在之后引用 a
未定义的行为。请阅读 this和 this了解堆。
此外,由于您将列表的头部作为指向指针的指针传递,当您在 prepend()
中更改 headPointer
指向的内容时,它会反射(reflect)在函数外部,因此你仍然有一个指向列表头部的指针。
|2|-->NULL
^
|
head
在调用 prepend()
之后
1) |5|--> |2|-->NULL
^
|
head
2) |5|----> |2|--->NULL
^
|
head
还记得有一些方法来访问堆分配的内存以便释放它。如果您没有任何方法指向堆上分配的内存,那么您将面临内存泄漏。
关于C - 单向链表中的指针和前置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45246257/