free(str);
printf("%d\n", str->listeners);
对 printf 的调用成功(与对 str 成员的任何其他调用一样)。这怎么可能?
free(str);
printf("%d\n", str->listeners);
对 printf 的调用成功(与对 str 成员的任何其他调用一样)。这怎么可能?
这是一个类比:假设您正在租一间公寓(即内存)并且您终止了租约但保留了密钥的副本(即指针)。如果它没有被拆除,如果没有更换锁等,你也许可以稍后回到公寓,如果你马上这样做,你可能会找到你离开它们的方式。但这是一个非常糟糕的主意,在可能的情况下,你会让自己陷入一堆麻烦中......
这被称为未定义的行为。您正在取消引用指向已释放内存的指针。任何事情都可能发生,即不能假设程序会崩溃或发生其他任何事情;行为未定义。
你只是(不)幸运。该代码表现出未定义的行为 - 任何事情都可能发生,包括看起来内存没有被释放。
内存被释放了,但是主动清除没有意义,所以它的原始内容很可能还在。但你不能依赖它。
只要str
不是NULL
并且相应的内存没有被其他分配覆盖它仍然可以工作,因为内存内容没有被更改free
(如果运行时没有覆盖内存区域free
)。但这绝对是未定义的行为,您不能依赖它以这种方式工作......
要记住的事情...
free()
永远不会将内存返回给操作系统。即使它在理论上能够做到这一点,它几乎永远不会真正发生。这是因为内存只能在通常 4kB 的对齐页面中返回,因为这就是 MMU 的工作方式,并且,如果找到它,将其撕掉可能会分割一个包含其上方和下方内存的块,从而使整个过程适得其反。(碎片化是有效利用动态内存的敌人。)