C 动态分配内存中free()的作用域是什么?

C 动态分配内存中free()的作用域是什么?,c,malloc,free,dynamic-memory-allocation,dynamic-allocation,C,Malloc,Free,Dynamic Memory Allocation,Dynamic Allocation,假设我有以下代码: typedef struct { int numBars; BarType *bars; } fooType; foo = (fooType *) malloc(sizeof(fooType)); foo->bars = (BarType *) malloc(sizeof(barType)); 呼叫免费(foo)也会免费酒吧吗?或者我需要这样做: free(foo->bars); free(foo); 直觉上,我觉得打免费电话(foo)就足够了——如

假设我有以下代码:

typedef struct {
  int numBars;
  BarType *bars;
} fooType;

foo = (fooType *) malloc(sizeof(fooType));
foo->bars = (BarType *) malloc(sizeof(barType));
呼叫免费(foo)也会免费酒吧吗?或者我需要这样做:

free(foo->bars);
free(foo);

直觉上,我觉得打免费电话(foo)就足够了——如果我不需要打免费电话(foo->numbar),我就不需要打免费电话(foo->bar)。但是我不必手动为numbar分配内存,而我为bar分配了内存。

对于每个
malloc
您都需要一个
免费
。没有什么是“自动”为你做的

请注意,与您的声明相反,您实际上不必为
分配任何内存,就像您不必为
numbar
分配内存一样。但是,您正在为
*条
分配内存


一颗星星可以在C中产生巨大的差异。

对于每个
malloc
你都需要一颗
免费的
。没有什么是“自动”为你做的

请注意,与您的声明相反,您实际上不必为
分配任何内存,就像您不必为
numbar
分配内存一样。但是,您正在为
*条
分配内存

一个星号可以在C中产生很大的不同。

free()
非常简单:它释放传递给它的内存块,该内存块必须来自
malloc()
。它不执行任何级联释放或其他清理。它也不会使指针为空以帮助捕获简单的逻辑错误

free(foo->bars);
free(foo);
foo = NULL;   /* good idea to do this, unless `foo` is going out of scope soon */
free()
非常简单:它释放传递给它的内存块,该内存块必须来自
malloc()
。它不执行任何级联释放或其他清理。它也不会使指针为空以帮助捕获简单的逻辑错误

free(foo->bars);
free(foo);
foo = NULL;   /* good idea to do this, unless `foo` is going out of scope soon */
通过使用:foo=(fooType*)malloc(sizeof(fooType));实际上,您正在为结构“fooType”分配内存,该结构只有一个指针来保存另一个已分配内存块的地址(malloced代表barType)

必须显式释放每个malloced内存。否则,如果您只使用free(foo)。这将导致内存泄漏()

使用这个:foo=(fooType*)malloc(sizeof(fooType));实际上,您正在为结构“fooType”分配内存,该结构只有一个指针来保存另一个已分配内存块的地址(malloced代表barType)


必须显式释放每个malloced内存。否则,如果您只使用free(foo)。这将导致内存泄漏()

你今天学到的教训是,在用C语言编程时,你永远不应该依赖直觉(或者获得更好的直觉)。你不需要免费调用numBar,因为你一开始没有使用它。你可以使用malloc'd条,因此你必须在某个时候释放它。记住
mallic
free
不知道分配的内存块中有什么;这只是一个斑点。因此,free不知道由
foo
指向的内存包含指针,更不用说指向另一个malloced块的指针了。此外,C中没有垃圾收集器来检测第二个块是孤立的并且应该被释放。您今天学到的教训是,在用C编程时,您永远不应该依赖直觉(或者获得更好的直觉)。您不需要在numBar上调用free,因为您一开始没有对它进行malloc。你可以使用malloc'd条,因此你必须在某个时候释放它。记住
mallic
free
不知道分配的内存块中有什么;这只是一个斑点。因此,free不知道由
foo
指向的内存包含指针,更不用说指向另一个malloced块的指针了。另外,C中没有垃圾收集器来检测第二个块是孤立的,应该被释放。@WeatherVane:不,指针不会超出范围。但指针对象将停止存在。“这很糟糕。”风向标:OP完全被一个星号弄糊涂了。我认为在这里吹毛求疵是正确的:—)+1@风向标它是否被重新分配是无关紧要的。一旦
foo
指向的内存被传递到
free
后,该指针将变得不确定。取消引用它会调用未定义的行为,无论它是否“有效”。如果
foo->bar
是存在的唯一指针变量,当
foo
被释放时,该变量保存从未释放的
bar
分配返回的地址,则格式良好的代码无法阻止随后的内存泄漏。如果真的设置为以非相反的方式释放分配顺序,则可以在其他指针变量(例如局部
void*p=foo->bar;
)中避开
foo->bar
。好的,如果您使用了
malloc()
要为包含另一个指向内存的指针的结构获取内存,也可以使用
malloc()
获取内存,请按相反顺序释放它们。对于一个不确定如何释放记忆的人来说,这是一个非常简单的观点,但你已经做了很多。@KerrekSB这就是我如何将我的思想围绕在这一点上的。当我调用free(foo)时,我就摆脱了指向条的指针,这是有道理的。虽然我以前分配内存的实际数据仍然存在,但由于指针丢失,我无法再访问它。@WeatherVane:不,指针不会超出范围。但指针对象将停止存在。“这很糟糕。”风向标:OP完全被一个星号弄糊涂了。我认为在这里吹毛求疵是正确的:—)+1@风向标它是否被重新分配是无关紧要的。一旦
foo
指向的内存被传递到
free
后,该指针将变得不确定。取消引用它会调用未定义的行为,无论它是否“有效”。如果
foo->bar
是存在的唯一指针变量,当
foo
被释放时,该变量保存从未释放的
bar
分配返回的地址,则格式良好的代码无法阻止随后的内存泄漏。你可以在其他指针变量中避开
foo->bar