问题描述
为什么当我必须声明一个指向节点(头)的指针时,我还必须为此分配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;
产生内存泄漏。
首先,为类型为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;
q
和p
指向相同的内存。
如果您发现任何这种混淆,可能是因为您期望指针不是简单值。但是,它们是简单的值,您需要一个基于该简单现实的心理模型。
,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声明内存的一部分时,您需要指向该内存的开头,以便可以访问它(因此,为什么需要指定大小,以便了解如何远不能读/写)。