在C中的堆上分配数组
Posted
技术标签:
【中文标题】在C中的堆上分配数组【英文标题】:Allocating array on heap in C 【发布时间】:2019-01-09 05:42:57 【问题描述】:我在堆上分配一组“Todo”结构,如下所示:
struct Todo *todos = malloc(n * sizeof(*todos));
我的理解是,我现在已经为我所有的 n 个 Todo 结构分配了内存。因此,如果我想保存一些值,我可以这样做:
todos[i].id = 1;
现在的问题是,如果我尝试使用 free(&todos[i]);
释放该内存,我会收到一条错误消息,告诉我我尚未分配该指针。
我现在的问题是,我是否只需要释放 todos
数组而不是单独释放每个元素?
【问题讨论】:
***.com/questions/4641476/… 你只需要在你保存的指针上调用 free,即free(todos);
。
Using Dynamic Memory allocation for arrays的可能重复
详细信息:“释放todos
数组” --> todos
是一个指针,而不是一个数组。 free(todos);
释放由todos
分配的内存指针。
【参考方案1】:
作为参考,你总是这样做:
WhateverTypeInTheWorld *var1 = malloc(whateveryouwanttocompletearray);
那么,你必须这样做
free(var1); /* use the same value you received from malloc() */
要返回内存...因为您只执行了一个malloc()
,您可以只执行一个free()
并将您从malloc()
获得的指针传递给它相同的指针。
当你写作时:
free(&todos[i].i);
您传递的是i-
esim 元素字段i
的地址,而不是您从malloc()
收到的指针。可能你明白你可以释放你收到的部分内存......但它不能那样工作......你以块的形式获取内存,并且你必须以从 malloc 收到的相同块返回它。
【讨论】:
【参考方案2】:Some programmer dude的answer的一点背景
C11 标准,7.22.3.3“free
函数”,第 2 段:
free
函数使ptr
指向的空间被释放,也就是说,可用于进一步分配。如果ptr
是空指针,则不会发生任何操作。否则,如果参数与内存管理函数之前返回的指针不匹配,或者如果空间已通过调用 free 或 realloc 被释放,行为未定义.
[我强调]
背景(第二级...)通常,您不仅收到了从指针开始的内存,而且在需要的指针地址之前还有某种(机器/操作系统特定的)控制块再次释放内存。
您可能会尝试通过读取指针之前的一些字节来查看此控制块(只是出于好奇),但请注意这实际上也是未定义的行为(所以不要曾经在生产代码中执行此操作!)并可能导致您的程序崩溃。
【讨论】:
【参考方案3】:您已经为您的Todo
结构所有分配了一个单独的内存块。您不能释放单个元素。就像您不应该释放非堆分配数组的元素一样。
对malloc
(或calloc
)的每次调用都应与对free
的单个调用匹配。
【讨论】:
感谢您的快速回复。因此,如果我像这样调用免费:free(todos);它会为我所有的 todo 结构释放整个内存块,对吗? @user2403221 是的,这是准确的。以上是关于在C中的堆上分配数组的主要内容,如果未能解决你的问题,请参考以下文章
C# / .Net Framework 中的堆大小 - 它可以增长吗?如何增长? [复制]