C-释放()后内存会发生什么变化?

C-释放()后内存会发生什么变化?,c,pointers,struct,C,Pointers,Struct,我有一个malloc所针对的结构类型,在我释放它之后,指针仍然指向我分配的数据。这是否仅仅是因为指针指向的内存是可用的,但尚未重新分配 #include <stdio.h> typedef struct Katze { int value; } Katze; int main () { Katze *mew = malloc(sizeof(Katze)); mew->value = 8910; free(mew); printf("m

我有一个malloc所针对的结构类型,在我释放它之后,指针仍然指向我分配的数据。这是否仅仅是因为指针指向的内存是可用的,但尚未重新分配

#include <stdio.h>

typedef struct Katze {
    int value;
} Katze;

int main () {
    Katze *mew = malloc(sizeof(Katze));
    mew->value = 8910;
    free(mew);
    printf("mew: %i\n", mew->value); // why does this still say "mew: 8910"?
}
#包括
类型定义结构{
int值;
}卡茨;
int main(){
Katze*mew=malloc(sizeof(Katze));
mew->value=8910;
免费(mew);
printf(“mew:%i\n”,mew->value);//为什么仍然显示“mew:8910”?
}

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

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

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

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

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

一旦指针被传递到
free()
,它指向的对象将到达其生命周期的末尾。任何引用指向对象的尝试都具有未定义的行为(即,不再允许取消引用指针)

更重要的是,指针本身的值变得不确定,因此任何引用指针值的尝试都具有未定义的行为。参考:6.2.4p2:

如果对象在其生存期之外被引用,则该行为为 未定义。当 它指向(或刚刚过去)的对象到达其生命周期的末尾

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


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

总之,是的。这是一种未定义的行为,意味着你有时运气好,有时运气不好。嘿,这是一个很好的答案。。。想要一个绿色的复选标记吗?我希望我的UB程序能运行飞行模拟人生。我的UB程序似乎给了我鼻魔…我猜在这个特殊情况下,UB释放了一小群有用的巧克力饼,然后迫使
printf()
打印原始值,而不是操作系统。标准中没有提到操作系统。并不是每个实现都有底层操作系统,甚至那些有底层操作系统的实现也可能完全在C库中进行管理。除此之外,这是一个很好的答案。@paxdiablo感谢您的更正。已编辑。指针本身变得不确定?我不太确定。标准中是否有引用说明了这一点?@paxdiablo:请参阅我的更新答案。@KeithThompson:指针不确定这一事实是否意味着所有涉及它的等式比较都会变成不确定的行为,或者仅仅有不确定的结果?当然,如果指针被释放,编译器就不能保证指针将来不会与指向有效数据结构的指针进行比较,但这似乎并不意味着鼻恶魔。在很多地方,人们可能会执行比较并最终不关心结果,但如果
foo
bar
是数据指针,
proc
是函数指针……我可以想象类似于
if((foo!=NULL)|(bar!=NULL))proc(foo,bar)如果代码可以保证在任何时候当
foo
bar
无效时,
proc
将引用一个只使用另一个(将是有效的)的函数。当然,在函数调用之外使用“if”可能不会有太大帮助,但是如果一个常见的情况是
foo
bar
都为null,并且函数调用会很昂贵,那么测试可以提高效率。@supercat:这是一个参考,因此是UB。表达式语句
ptr也是一个参考。除了作为
sizeof
&
的操作数,或在赋值的LHS上,几乎所有对名称的引用都读取值(在抽象机器中),因此具有未定义的行为。