C - 单向链表中的指针和前置

标签 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 中的值,它又是 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未定义的行为。请阅读 thisthis了解堆。

此外,由于您将列表的头部作为指向指针的指针传递,当您在 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/

相关文章:

c++ - C++ 中的对象分配

c++ - 指向指针 : managing strings for different languages 的指针数组

c++ - 空指针 : how to use as a general class pointer?

python - 在 C 和 Python 之间传递 C++ 指针

c++ - 使用 MI 命令在 GDB 中发送 'monitor reset halt'

c - 在屏幕底部保持提示消息应用程序

FORTRAN 中子程序的指针

c++ - 传递大物体的最快方法

c - SHA - 程序输出不同于 sha512sum 命令

c++ - 从静态库中删除所有符号是否会阻止链接?