C - free() 之后内存会发生啥? [复制]

Posted

技术标签:

【中文标题】C - free() 之后内存会发生啥? [复制]【英文标题】:C - What Happens To Memory After free()? [duplicate]C - free() 之后内存会发生什么? [复制] 【发布时间】:2013-09-06 02:04:22 【问题描述】:

我有这个我 malloc 的结构类型,在我释放它之后,指针仍然指向我分配的数据。这仅仅是因为指针指向的是空闲但尚未重新分配的内存吗?

#include <stdio.h>

struct S 
    int value;


int main () 
    S *s = malloc(sizeof(struct S));
    s->value = 8910;
    free(s);
    printf("s: %i\n", s->value);

【问题讨论】:

总之,是的。这是未定义的行为,这意味着您有时会很幸运,有时却没有那么幸运。 【参考方案1】:

释放的内存不再属于你。但这并不意味着它会以任何方式消失或改变。为什么你的程序会打扰?这将是浪费时间。它可能只是将内存标记为可供后续malloc()s 使用,仅此而已。或者它可能不会。使用不属于您的内存可能会做任何事情:返回错误值、崩溃、返回正确值或运行飞行模拟器游戏。这不是你的;不要惹它,你永远不必担心它会做什么。

【讨论】:

我希望 my UB 程序能够运行模拟飞行。 我的 UB 程序似乎只是给我鼻恶魔...... 我的猜测是,在这种特殊情况下,UB 会释放一小群有用的巧克力蛋糕,然后他们会强制 printf() 打印原始值。【参考方案2】:

C 标准定义了free 函数的行为:

free 函数使 ptr 指向的空间变为 已解除分配,即可供进一步分配。

这意味着以后对malloc(或其他东西)的调用可能会重新使用相同的内存空间。

只要将指针传递给free(),它所指向的对象就会到达其生命周期的终点。任何引用指向对象的尝试都有未定义的行为(即,您不再被允许取消引用指针)。

不仅如此,指针本身的值变得不确定,因此任何引用指针值的尝试都有未定义的行为。参考:N15706.2.4p2:

如果一个对象在其生命周期之外被引用,则行为是 不明确的。当指针的值变得不确定时 它指向(或刚刚过去)的对象达到其生命周期的终点。

free() 的参数确实是按值传递的(就像所有 C 函数参数一样),因此 free 不能实际修改指针。一种思考方式是,指针在调用前后具有“相同”的值,但该值在调用前有效,在调用后不确定。

尝试引用指针值,甚至取消引用它,可能会显示“工作”。这是未定义行为的许多可能症状之一(可以说是最糟糕的,因为它很难检测和诊断错误)。

【讨论】:

指针本身变得不确定?我不太确定。标准中是否有说明这一点的参考资料? @paxdiablo:查看我的更新答案。 @KeithThompson:指针不确定这一事实是否意味着所有涉及它的相等比较都成为未定义的行为或仅具有不确定的结果?当然,如果指针被释放,编译器就不能保证该指针将来不会与指向有效数据结构的指针相比较,但这似乎并不意味着鼻恶魔。可能没有很多地方可以进行比较并最终不关心结果,但是如果foobar 是数据指针,proc 是函数指针... ...如果代码可以保证foobar 无效时,proc 将引用仅使用的函数,我可以想象类似if ((foo != NULL) || (bar != NULL)) proc(foo,bar);另一个(这将是有效的)。可以肯定的是,在函数调用之外使用“if”可能不会有太大帮助,但如果常见的情况是 foobar 都为 null 并且函数调用会很昂贵,那么测试可以提高效率。 @supercat:这是一个参考,因此是 UB。表达式语句ptr; 也是一个引用。除了作为 sizeof&amp; 的操作数或在赋值的 LHS 上之外,几乎所有对名称的引用都会读取值(在抽象机器中),因此具有未定义的行为。【参考方案3】:

free() 只是向语言实现或操作系统声明不再需要内存。当它被覆盖时未定义行为。

【讨论】:

不是操作系统。该标准没有说明操作系统。并非每个实现都有一个底层操作系统,甚至那些确实可以在 C 库本身内完全管理它的实现。除此之外,一个很好的答案。 @paxdiablo 感谢您的更正。已编辑。

以上是关于C - free() 之后内存会发生啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

请问C语言free(p)释放p所指向的动态内存后p指向哪?是NULL还是随机还是啥呢?

malloc 和 free 在 C 中是如何实现的? [复制]

C alloca 函数 - 当试图分配太多内存时会发生啥

c语言中,malloc和free是啥意思?

为啥在使用 malloc() 和 free() 后,两个内存位置会发生变化?

当 python 添加小整数时,幕后会发生啥? [复制]