【问题标题】:Dynamic memory allocation for node in linked list链表中节点的动态内存分配
【发布时间】:2020-12-08 23:25:00
【问题描述】:

为什么当我必须声明一个指向节点(头)的指针时,我还必须为它分配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*),这里很多人强烈建议你不要写。 (它在 C++ 中是必需的,但这是一种不同的语言,在 C++ 中你不应该使用 malloc。)
  • (node*) 只是将结果转换为指向node 的指针,head = NULL 清除列表(将根设置为NULL 并且不应该在这里因为必须使用free 释放malloc 返回值)。
  • 好的,但我不会将结果转换为指向已经声明“head = ....”的节点的指针@רועיאבידן
  • 是的,这就是为什么@rici 正确地说,你不必这样做(在 C 中,而不是 C++ 中)。

标签: c memory-leaks linked-list dynamic-memory-allocation


【解决方案1】:

这段代码sn-p

node *head;

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

产生内存泄漏。

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

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

然后立即覆盖指针的值。

head = NULL;

因此分配的内存地址丢失,分配的内存无法释放。

代码 sn-p 没有任何意义。写就够了

node *head = NULL;

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

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

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

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

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

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

【讨论】:

  • 它是否是多余的,因为我已经将分配的内存分配给了一个声明“head = ...”的节点,因为 head 已经是一个节点?
  • @Boninissimo head 是指针类型节点 * 的变量,没有创建类型节点的对象。那就是指针还没有指向任何有效的对象。
【解决方案2】:

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 声明一段内存时,您需要指向该内存的开头,以便您可以访问它(因此为什么需要指定大小以便您知道如何远读/写)。

【讨论】:

  • 请在您的答案中包含来自链接的重要代码。链接可能会失效,然后这些信息就会丢失。
【解决方案3】:

在 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 指向同一个内存。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-30
    • 2019-10-14
    • 2014-09-29
    • 2013-05-14
    • 1970-01-01
    • 2021-09-20
    • 2013-08-26
    • 2013-04-14
    相关资源
    最近更新 更多