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

C 链表中节点的动态内存分配,c,memory-leaks,linked-list,dynamic-memory-allocation,C,Memory Leaks,Linked List,Dynamic Memory Allocation,为什么当我必须声明指向节点(头)的指针时,我还必须为它分配malloc或calloc内存?我看到生成列表(此处未导入)的代码也运行良好,无需为其分配内存,只需声明node*head typedef struct str_node{ int data; struct str_node *next; }node; int main(){ node *head; head = (node*) malloc(sizeof(node)); head = NUL

为什么当我必须声明指向节点(头)的指针时,我还必须为它分配
malloc
calloc
内存?我看到生成列表(此处未导入)的代码也运行良好,无需为其分配内存,只需声明
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;
产生内存泄漏

首先,为
节点
类型的对象分配内存,并将其地址分配给指针

head = (node*) malloc(sizeof(node));
然后指针的值立即被覆盖

head = NULL;
因此,已分配内存的地址丢失,无法释放已分配内存

代码片段没有任何意义。写就足够了

node *head = NULL;
在这种情况下,您最初将有一个空列表

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

函数
malloc
返回类型为
void*
的指针。
void*
类型的指针可以指定给任何其他对象类型的指针。所以在C中,铸造是多余的

<>在C++中,您明确地将类型“<代码>空白> <代码>的指针转换为对象指针的类型,该类型指针被指定为类型<代码> VUL**/COD>的指针。 此外,当我写head=NULL时,我设置了指针的地址 去空还是什么


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

Malloc用于分配指定大小的内存块,即在本例中,它是(sizeof(node))链接列表中的“项”。这可以用来增加您的链接列表

(节点*)用于分配内存类型。

我建议你读这本书 它将解释一些基本原理

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


指针将编译器指向内存地址,因此当您使用malloc声明内存段时,您需要指向该内存段的开头,以便可以访问它(因此,您需要指定大小,以便知道读/写的距离)。

在C中,指针是值,与整数类似。当你写作时:

int a;
a = 3;
int* p;
p = NULL;
将值3存储到变量
a

当你写作时:

int a;
a = 3;
int* p;
p = NULL;
将值
NULL
存储到变量
p
中。指针没有什么特别之处。赋值不以任何方式取决于
p
的值,即它可能指向或可能不指向的内容。(在本例中,它没有指向任何东西,但这与此无关。)

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

int* p;
p = malloc(sizeof *p);
由于
p
被声明为指向
int
的指针,因此预期
p
指向的内存可以容纳
int
。(它还没有,但它可以。)但是你可以传递指针(作为一个值),而不会对指向的内存中存储的整数(如果有的话)产生任何影响。比如说,

int* q = p;
q
p
指向同一内存


如果您发现其中任何一个问题令人困惑,可能是因为您希望指针不是简单的值。然而,它们是简单的价值观,你需要一个基于简单现实的心智模型。

你不必写
(node*)
,这里的许多人强烈建议你不要写。这是一个不同的语言,但是C++是不一样的,C++中不应该使用<代码> Malc C <代码>。)代码>(节点*)< /C> >将结果转换为一个指向<代码>节点>代码>,<代码>头= null < /Cord> >清除列表。(将根设置为
NULL
,并且不应该在这里,因为
malloc
返回值必须使用
free
释放)。请参见Ok,但我不会将结果转换为指向已声明“head=…”的节点的指针。@rici正确地说,这就是为什么您不必这样做的原因(在C中,而不是在C++)。是否因为我已将分配的内存分配给声明“head=…”的节点而冗余由于head已经是节点?@Boninsimo head是指针类型node*的变量,因此未创建任何类型node的对象。也就是说,指针尚未指向任何有效对象。请在答案中包含链接中的重要代码。链接可能会消失,然后此信息将丢失。