我试图理解前置后面的指针逻辑。
我声明了一个结构如下:
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都超出了范围。 (?)
这一切如何加起来?是否有更简单的方法来描述情况或实施前置?
答案 0 :(得分:2)
然后,new_node和headPointer都超出了范围。 (?)
在prepend()
newnode
结束时超出了范围但没有分配的内存,因为它是在堆上分配的。如果它类似int a
,那么在结束时prepend()
,a
超出范围并在引用a
之后将是未定义的行为。请阅读this和this以了解堆。
此外,由于您将列表的头部作为指针传递给指针,当您更改headPointer
指向prepend()
内部的内容时,它会反映在函数外部,因此您仍然可以指向头部列表。
|2|-->NULL
^
|
head
致电prepend()
1) |5|--> |2|-->NULL
^
|
head
2) |5|----> |2|--->NULL
^
|
head
还记得有一些方法可以访问堆分配的内存以释放它。如果你没有任何方法指向分配在堆上的内存,那么你就会留下内存泄漏。