在C

时间:2018-08-01 15:16:22

标签: c pointers

我正在堆上分配“ Todo”结构数组,如下所示:

struct Todo *todos = malloc(n * sizeof(*todos));

我的理解是,我现在已经为所有n个Todo结构分配了内存。因此,如果要保存一些值,我可以例如执行以下操作:

todos[i].id = 1;

现在的问题是,如果我尝试使用free(&todos[i]);释放该内存,则会收到一条错误消息,告诉我尚未分配该指针。

现在的问题是,我是否只需要释放todos数组,而不是每个元素都单独释放?

3 个答案:

答案 0 :(得分:5)

您为Todo结构的 all 个分配了一个内存块。您不能释放单个元素。就像您不应该释放非堆分配数组中的元素一样。

malloc(或calloc)的每次调用应与对free单个调用相匹配。

答案 1 :(得分:2)

Some programmer dudeanswer的背景知识

C11标准,7.23.2.3“ free函数”,第2段:

  

free函数导致ptr指向的空间被释放,即可以用于进一步分配。如果ptr为空指针,则不执行任何操作。否则,如果参数与先前由内存管理函数返回的指针不匹配,或者如果通过调用free或realloc释放了空间,则行为是不确定的 >。

[我强调]

背景(第二层...)通常是,您不仅从指针处开始接收内存,而且在需要指针地址之前还有某种(特定于机器/操作系统的)控制块重新释放内存。

您可能会尝试通过在指针之前读取一些字节来窥视此控制块(出于好奇),但是要注意,这实际上也是未定义的行为(因此请不要永远在生产代码中执行此操作!),可能会导致程序崩溃。

答案 2 :(得分:0)

作为参考,请始终这样做:

WhateverTypeInTheWorld *var1 = malloc(whateveryouwanttocompletearray);

然后,您必须做

free(var1);  /* use the same value you received from malloc() */

返回内存...就像您只做一个malloc()一样,您只能做一个free()并传递给它与您从{得到的指针相同 {1}}。

写时:

malloc()

您正在传递free(&todos[i].i); esim元素字段i-的地址,而不是您从i收到的指针。也许您了解您可以释放收到的部分内存...但是这种方式不起作用...您将内存分成块,然后必须以与从malloc收到的相同的块返回。 / p>