C 中的 free() 函数对我不起作用
我一直在尝试使用free()
释放通过malloc()
分配的内存。
它释放了一些结构,但保留了一些结构,并且它们仍然与其子结构保持联系。它也永远不会释放二叉树的根(gRootPtr)
。
我正在使用 Xcode 来查明二叉树使用的内存是否已被释放,并使用 if 语句。
我用来释放内存的代码:
void FreeMemory(InfoDefiner *InfoCarrier)
{
if ((*InfoCarrier) != NULL) {
FreeMemory((&(*InfoCarrier)->left));
FreeMemory((&(*InfoCarrier)->right));
free((*InfoCarrier));
}
}
我用来查看内存是否已被释放的代码。
if (gRootPtr != NULL) {
return 1;
}
else{
return 0;
}
I have been trying to free memory allocated via malloc()
using free()
.
Some of the structs it does free but leaves some the way they were and they also remain linked to their children. It also never frees the root (gRootPtr)
for a binary tree.
I am using Xcode to find out if the memory used by the binary tree has been freed and also use the if statement.
Code I am using to free the memory:
void FreeMemory(InfoDefiner *InfoCarrier)
{
if ((*InfoCarrier) != NULL) {
FreeMemory((&(*InfoCarrier)->left));
FreeMemory((&(*InfoCarrier)->right));
free((*InfoCarrier));
}
}
Code I am using to see if the memory has been freed.
if (gRootPtr != NULL) {
return 1;
}
else{
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,free 不会改变指针本身。
如果您希望指针返回 NULL,您必须自己执行此操作。
其次,没有保证释放后指针指向的内存会发生什么:
请注意,这意味着您无法实际测试 free() 是否有效。严格来说,完全不执行任何操作来实现
free()
是合法的(当然,如果是这种情况,您最终会耗尽内存)。First, free does not change the pointer itself.
If you want the pointer to go back to NULL, you must do this yourself.
Second, there are no guarentees about what will happen to the memory pointed to by the pointer after the free:
Note that this means that you cannot actually test if
free()
works. Strictly speaking, it's legal forfree()
to be implemented by doing absolutely nothing (although you'll run out of memory eventually if this is the case, of course).该检查不会检查变量是否已释放。请注意,
free(pointer)
不会将该指针设置为 NULL。如果您希望出现这种情况,则必须自己设置它,这是 C 中的常见习惯用法:表示您已经释放了该指针。
That check won't check if the variable is freed. Note that
free(pointer)
does not set that pointer to NULL. If you want that to be the case, you have to set it yourself, and it is a common idiom in C:to signal that you already freed that pointer.
调用 free 不会将指针设置为 NULL。你必须自己做。
Calling free does not set the pointer to NULL. You have to do that yourself.
free()
失败的唯一原因是您给它的指针没有取消引用已分配的堆。此行为已明确定义,free()
将起作用,否则您的程序将因访问冲突而停止。为此,最好在释放指针后重新初始化它们。这可以让您:
确保您不会在已分配的指针之上进行分配(从而丢失对原始块的引用并导致泄漏)(尽管有 realloc())。
确保您不释放最近释放的内存或从未分配的内存
通过测试看看是否指针已初始化(或 NULL)。
最好手动执行此操作并养成这样做的习惯。我见过一些非常复杂的重新实现
free()
的方法,以便自动重新初始化指针,就像这个小宝石一样,它也尝试避免释放不属于“的内存” t allocate:请不要使用该代码,由于取消引用类型双关指针,它会在严格的平台上严重崩溃。另外,如果指针是字符串文字怎么办?
相反,只需确保跟踪指针并在释放后初始化它们即可。
The only reason
free()
would fail is if the pointer you give it does not dereference to allocated heap. This behavior is clearly defined,free()
will either work, or your program will halt due to an access violation.It is good practice to re-initialize your pointers after freeing them, for just this purpose. This lets you:
Make sure you don't allocate on top of an already allocated pointer (thus losing the reference to the original blocks and causing a leak) (realloc() notwithstanding).
Make sure you don't free recently freed memory, or memory that was never allocated
Both become easy by testing to see if the pointer is initialized (or, NULL).
It's best to just do this manually and get in the habit of doing so. I have seen some very convoluted ways of re-implementing
free()
so that re-initializes the pointer automatically, like this little gem that also attempts avoid freeing memory that wasn't allocated:Please, don't use that code, it will break horribly on strict platforms due to dereferencing a type punned pointer. Additionally, what if the pointer is a string literal?
Instead, just make sure you keep track of your pointers and initialize them after freeing.
函数
free
需要一个指向已分配内存的指针,但是它不会将该指针设置为NULL
,事实上它无法这样做(它需要采取指针的地址)。此场景的典型用例是:
The function
free
takes a pointer to allocated memory, it does not however set that pointer toNULL
, in fact there is no way it could do so (it would need to take the address of a pointer for that).Typical use case in this scenario is: