链表中节点的动态内存分配

问题描述

为什么当我必须声明一个指向节点(头)的指针时,我还必须为此分配malloccalloc的内存?我看到生成列表(此处未导入)的代码也可以很好地工作,而无需为其分配内存,而只是声明node *head

typedef struct str_node{
    int data;
    struct str_node *next;
}node;

int main(){

    node *head;

    head = (node*) malloc(sizeof(node));
    head = NULL;

为什么当我如上所述分配内存时,我必须写(node*)?因为我是在头上执行,所以它是否已经分配给结构节点?该行代码的确切含​​义是什么?而且,当我写head = NULL时,我将指针头的地址设置为NULL还是什么?

解决方法

此代码段

node *head;

head = (node*) malloc(sizeof(node));
head = NULL;

产生内存泄漏。

首先,为类型为node的对象分配了一个内存,并将其地址分配给了指针head

head = (node*) malloc(sizeof(node));

,然后立即覆盖指针的值。

head = NULL;

结果,分配的内存地址丢失并且分配的内存无法释放。

该代码段没有任何意义。足够写

node *head = NULL;

在这种情况下,您最初将有一个空列表。

为什么当我像上面那样分配内存时,我必须写(node *)?

函数malloc返回类型为void *的指针。类型void *的指针可以分配给任何其他对象类型的指针。因此,在C中进行强制转换是多余的。

在C ++中,必须显式地将类型为void *的指针转换为对象指针的类型,类型为void *的指针已分配给该对象指针。

此外,当我写head = NULL时,我是否设置了指针的地址 转到NULL还是什么?

您没有设置指针本身的地址。该指针由编译器分配,并具有自动存储持续时间。您将类型为head的变量node *的值设置为NULL。

,

在C中,指针是值,就像整数一样。当您写时:

int a;
a = 3;

您将值3存储到变量a中。

撰写时:

int* p;
p = NULL;

您将值NULL存储到变量p中。 指针没有什么特别的。赋值并不以任何方式取决于p的值,即它可能指向或不指向的内容。 (在这种情况下,它什么也没有指向,但这无关紧要。)

malloc返回一个指向存储区的指针,该存储区如上所述。该指针没有固有的元数据。 malloc不需要任何超出存储区域大小的信息。特别地,它不知道(或不在乎)该存储区将用于什么。产生该值后,您可以按照自己的意愿处理它,例如:

int* p;
p = malloc(sizeof *p);

由于p被声明为指向int的指针,因此可以预期p所指向的内存可以容纳int。 (它还没有,但是可以。)但是,您可以传递指针(作为一个值),而对存储在所指向内存中的整数(如果有)没有任何影响。例如,在

之后
int* q = p;

qp指向相同的内存。

如果您发现任何这种混淆,可能是因为您期望指针不是简单值。但是,它们是简单的值,您需要一个基于该简单现实的心理模型。

,

Malloc用于分配指定大小的内存块,在这种情况下,它是(sizeof(node)),它是链表中的一个``项目''。这可以用来允许您的链表增长。

(node *)用于分配内存类型。 Example from GeeksForGeeks

我建议您阅读https://www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-malloc-calloc-free-and-realloc/ 它将解释一些基本原理。

最后回答这个问题:“为什么当我必须声明一个指向节点(头)的指针时,我还必须为其分配带有malloc或calloc的内存?”

指针将编译器指向一个内存地址,因此当您使用malloc声明内存的一部分时,您需要指向该内存的开头,以便可以访问它(因此,为什么需要指定大小,以便了解如何远不能读/写)。