0
free(str);
printf("%d\n", str->listeners);

对 printf 的调用成功(与对 str 成员的任何其他调用一样)。这怎么可能?

4

5 回答 5

4

这是一个类比:假设您正在租一间公寓(即内存)并且您终止了租约但保留了密钥的副本(即指针)。如果它没有被拆除,如果没有更换锁等,你也许可以稍后回到公寓,如果你马上这样做,你可能会找到你离开它们的方式。但这是一个非常糟糕的主意,在可能的情况下,你会让自己陷入一堆麻烦中...​​...

于 2012-05-06T18:43:25.573 回答
2

这被称为未定义的行为。您正在取消引用指向已释放内存的指针。任何事情都可能发生,即不能假设程序会崩溃或发生其他任何事情;行为未定义

于 2012-05-06T18:35:50.513 回答
2

你只是(不)幸运。该代码表现出未定义的行为 - 任何事情都可能发生,包括看起来内存没有被释放。

内存释放了,但是主动清除没有意义,所以它的原始内容很可能还在。但你不能依赖它。

于 2012-05-06T18:36:17.827 回答
1

只要str不是NULL并且相应的内存没有被其他分配覆盖它仍然可以工作,因为内存内容没有被更改free(如果运行时没有覆盖内存区域free)。但这绝对是未定义的行为,您不能依赖它以这种方式工作......

于 2012-05-06T18:36:55.857 回答
0

要记住的事情...

  • 在几乎所有当前操作系统上,free()永远不会将内存返回给操作系统。即使它在理论上能够做到这一点,它几乎永远不会真正发生。这是因为内存只能在通常 4kB 的对齐页面中返回,因为这就是 MMU 的工作方式,并且,如果找到它,将其撕掉可能会分割一个包含其上方和下方内存的块,从而使整个过程适得其反。(碎片化是有效利用动态内存的敌人。)
  • 此外,大多数程序通常只是使用更多内存,因此花在寻找真正返回操作系统的东西上的时间将被完全浪费掉。如果它没有返回给操作系统然后受到保护,那么当你触摸它时它就不会成为你的程序的核心。
  • 因此,相反,您提供给 free 的块只是放在一个列表或其他一些数据结构上,然后可能合并到它上面或下面的块中。
  • 记忆仍然存在并且可以访问。某些块可能会被 malloc() 和 free() 后面的库代码的指针和其他内部结构覆盖。但它可能不是。
  • 最终,它可能会在您的程序的其他地方交还。但它可能不是。
于 2016-06-17T21:10:39.607 回答