我正在堆上分配“ Todo”结构数组,如下所示:
struct Todo *todos = malloc(n * sizeof(*todos));
我的理解是,我现在已经为所有n个Todo结构分配了内存。因此,如果要保存一些值,我可以例如执行以下操作:
todos[i].id = 1;
现在的问题是,如果我尝试使用free(&todos[i]);
释放该内存,则会收到一条错误消息,告诉我尚未分配该指针。
现在的问题是,我是否只需要释放todos
数组,而不是每个元素都单独释放?
答案 0 :(得分:5)
您为Todo
结构的 all 个分配了一个内存块。您不能释放单个元素。就像您不应该释放非堆分配数组中的元素一样。
对malloc
(或calloc
)的每次调用应与对free
的单个调用相匹配。
答案 1 :(得分:2)
Some programmer dude的answer的背景知识
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>