0

当我在大学实现我自己的 malloc() 版本时,我使用了两个链表:一个空闲列表和一个分配的缓冲区列表(在我用完时穿插着对 sbrk 的调用)。但是现在我遇到了现实世界的问题:我们的软件 malloc 的缓冲区并将它们放在链表上,几个小时后它们可能会被一个或另一个函数中的代码释放。但是很少有代码具有与 malloc() 相同的函数中的 free()

这有时会导致 malloc 的缓冲区被释放两次。在 Solaris 下,这显然不是问题,因为该应用程序已经运行了很长时间。但是在Linux(RH)下运行代码这个bug突然就醒了。

我不知道 malloc() 的内部行为,但它显然是依赖于实现的。我不知道 Linux/gcc 实现是否维护分配的缓冲区列表。(免费列表是必须的;分配的列表?我认为不是那么多。)这让我想到了我的问题:

  1. malloc 的这种实现是否使用分配的内存区域列表?
  2. 是否有一个函数(我认为非官方的)可以扫描该列表以查找给定的指针?

在阅读了我的 hmjd 对 ant2009 的问题的回复后,如果上述答案是肯定的,我的方案是用扩展代码的宏替换对 free() 的调用:

  • 检查指针是否为空,在这种情况下它会跳过接下来的几个步骤
  • 调用这个神秘的函数以确保它仍然是 malloc'd
  • Frees 是使用 free() 的书
  • 将指针归零作为它已经被释放的信号;不要再费心释放了。

这样的功能肯定不在我的手册页中,但我很欢迎。(在我写这篇文章时,我即将下载 glibc-2.17.tar.xz;也可以在那里找到我的答案。)

谢谢。(即使只是读到这里!)

——雅各布

4

1 回答 1

1

这是大问题,而不是您的崩溃...

您无法根据地址判断第二个免费对象是用于您的对象还是同时已分配并正在使用的另一个对象...

至于你的观点:

  • 检查指针是否为空,在这种情况下它会跳过接下来的几个
    • free()在所有现代实现中都是空安全的,没关系。
  • 步骤调用这个神秘的函数以确保它仍然是 malloc'd
    • 你仍然不知道它是否是你想要的对象。
  • Frees 是本书使用 free() 将指针归零作为它的信号
    • 我不知道这是什么意思
  • 已经被释放;不要再费心释放了。
    • 这是问题的症结所在,一旦你到了这里,你就处于糟糕的状态。

你有一个错误,你需要克服修复 C 语言的冲动,并修复你的代码......

NULL'ing 指针很好,但这只是一个步骤,因为一旦您将指针的副本交给了...将您的本地副本归零不会使另一个副本归零...

如果这是一个肯定需要它的地方,你可以使用另一个级别的冷漠。

void ** handle;
void ** handle2;

void * obj = malloc(5);

handle = &obj;
handle2 = &obj;

free(*handle);
*handle = NULL;

free(*handle2);
*handle2 = NULL;

那么归零obj可能会有所帮助......

于 2013-05-10T19:39:58.813 回答