关于free()在C中如何工作的澄清-

关于free()在C中如何工作的澄清-,c,C,我的问题是关于在C中何时使用free()合适。我使用的是gcc 4.3.2 假设,如果必须在链表中释放一堆内存,理想的方法是(我猜): 现在,假设我在下面的ADT上做类似的事情: 一个指针“VertexNode”,它还有两个指针:“Vertex”和“Edge”(例如)。相当于说: struct vertexnode { vertex *v; edge *e; } typedef struct vertexnode* VertexNode; 稍后,在初始化实例时,我将执行以下

我的问题是关于在C中何时使用free()合适。我使用的是gcc 4.3.2

假设,如果必须在链表中释放一堆内存,理想的方法是(我猜):

现在,假设我在下面的ADT上做类似的事情:

一个指针“VertexNode”,它还有两个指针:“Vertex”和“Edge”(例如)。相当于说:

struct vertexnode
{
     vertex *v;
     edge *e;
}
typedef struct vertexnode* VertexNode;
稍后,在初始化实例时,我将执行以下操作-

VertexNode V = malloc(sizeof(struct vertexnode));
V->v = malloc(sizeof(vertex));
因此,最终在释放时:我使用了与链接列表相同的类比

free(V->v);
free(V);
这会导致运行时错误,当我注释掉“free(V->V)”时,程序运行良好。 我的问题是:

a) 仅仅做免费(V)就足够了吗?我的意思是,free()是否在给定指针内的所有指针上递归工作

b) 如果没有,这种情况下是否存在内存泄漏?我该如何预防这种情况

c) 最后,有没有办法跟踪malloc()和 他们中有多少人被free()释放了


我很抱歉问这么长的问题。提前感谢您的时间和耐心。

不,free不会递归工作,因此您确实会有内存泄漏。您正在发生的运行时错误可能是一个逻辑错误(可能是
V->V
NULL
或者您在释放之前没有分配它)


如果您使用的是linux,那么使用valgrind可以帮助您分析程序并提及泄漏错误。使用
cc*.c-ggdb
编译,然后运行
valgrind--leakcheck=full./a.out
将输出泄漏错误。

否,free不会递归工作,因此确实存在内存泄漏。您正在发生的运行时错误可能是一个逻辑错误(可能是
V->V
NULL
或者您在释放之前没有分配它)


如果您使用的是linux,那么使用valgrind可以帮助您分析程序并提及泄漏错误。使用
cc*.c-ggdb
编译,然后运行
valgrind--leakcheck=full./a.out
将输出泄漏错误。

问题是:您需要确保您试图释放的指针实际上已初始化

在调用
free
之前,我还要检查
V->V
是否为
NULL
(请参阅我对您问题的评论)


free
不是“递归的”。如果不释放
e
v
(在您的示例中)也会导致内存泄漏。

问题是:您需要确保尝试释放的指针实际上已初始化

在调用
free
之前,我还要检查
V->V
是否为
NULL
(请参阅我对您问题的评论)


free
不是“递归的”。如果不释放
e
v
(在您的示例中)也会导致内存泄漏。

要回答您的问题:

a) 否。free()不会递归释放结构的成员指针

b) 是的,在这种情况下内存泄漏。您必须用代码释放所有分配的内存


c) 您可以使用工具来检查内存泄漏,例如valgrind,这很容易。我知道有些项目实现了自己的内存管理,它们将malloc和free封装在自己的API中,这样您就可以在它们的API中跟踪内存使用情况。

回答您的问题:

a) 否。free()不会递归释放结构的成员指针

b) 是的,在这种情况下内存泄漏。您必须用代码释放所有分配的内存

c) 您可以使用工具来检查内存泄漏,例如valgrind,这很容易。我知道有些项目实现了自己的内存管理,它们在自己的API中封装malloc和free,这样您就可以在它们的API中跟踪内存使用情况。

A:
free()
不会递归工作。 -如果您使用的是ADT概念,那么我建议您通过创建
createVertexNode()
函数在类型内执行分配,并在
freeVertexNode()函数内执行检查和解除分配

B:如果你不能释放它,那将是内存泄漏 -您可以通过确保ADT函数检查并释放它分配的内存来避免它,或者

C:使用内存泄漏检测器。VisualStudio有一个内置的,或者使用其他的,比如valgrind或RationalPurify。我确信有更多的免费开源库,最简单的方法是重写malloc()和free()调用。A:
free()
不能递归工作。 -如果您使用的是ADT概念,那么我建议您通过创建
createVertexNode()
函数在类型内执行分配,并在
freeVertexNode()函数内执行检查和解除分配

B:如果你不能释放它,那将是内存泄漏 -您可以通过确保ADT函数检查并释放它分配的内存来避免它,或者


C:使用内存泄漏检测器。VisualStudio有一个内置的,或者使用其他的,比如valgrind或RationalPurify。我确信有更多的免费开源库,最简单的方法是覆盖malloc()和free()调用

为了实现完整的内存管理,我希望有一个内存池。这将消除为每个被调用的malloc调用多个free的痛苦。我使用ApachePortableRuntime(APR)进行内存池。只需在开始初始化时分配一块内存即可。系统将为每个指针分配您想要的数量。最后只需打一个电话释放所有内存。这比执行大量导致内存泄漏的malloc和free要高效得多


作为旁注。如果不使用内存池,我建议您使用valgrind来测试您的应用程序。事实上,您应该始终使用valgrind。

对于完整的内存管理,我希望有一个内存池。这将消除所有的痛苦,必须呼吁一个号码的fr
free(V->v);
free(V);
typedef struct pointless {
    struct pointless * next;
}pl;

pl * head = malloc(sizeof(pl)); // head gets 4 bytes
pl->next = malloc(sizeof(pl));  // head->next gets 4 bytes
free(head);  // head's allocated 4 bytes are deleted
int total_mem = 0;

head = malloc((total_mem += sizeof(pl)));

free(head);
total_mem -= sizeof(head);