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