使用malloc()函数分配的缓冲区识别

4

有没有办法识别一个缓冲区是否是通过'malloc'函数分配的?类似于以下签名的函数:

bool is_malloced(void *buf);

这种机制在posix中存在吗?

bool is_malloced(void *buf) { free(buf); return true; } ;) 说真的,我不知道有这样的东西。 - Daniel Fischer
不过,您可以编写自己的分配器来支持此功能。但是,您为什么认为需要这样的函数呢? - TJD
我其实并不需要这样的函数,只是好奇而已... - Woodrow Douglass
https://dev59.com/h0XRa4cB1Zd3GeqPuLs_ - effeffe
1
你最好的选择是用一个库预加载机制或其他方式,替换malloc为自己的实现,并在你自己的实现中包装POSIX malloc调用,将指针标记为“已分配”,并存储在某种映射表中。问题在于没有一种可移植的方式来覆盖malloc(在GNU C中有malloc_hook)或链接到另一个malloc - Armen Michaeli
@TJD,只需要一个malloc/free的包装器就足够了,这些包装函数将会在自己的动态或静态表(哈希表)中添加/删除已分配块的指针。 - pmod
3个回答

2
不行。C11和POSIX都没有提供任何这样的机制。

1

如果你是一个认真的人,你实际上可以做到:

Hash   *hsh;   /* global hash already initialized. */
void *custom_malloc(size_t size)
{
     void  *ptr;

     ptr = malloc(size);

    hash_add(hsh, ptr);
  return ptr;
}

/* tester */

_Bool malloced(void *ptr)
{
      if(hash_retrieve(hsh, ptr))
           return TRUE;
      return FALSE;
}

当然,这样做是疯狂的,但确实可以。


这是疯狂的想法。这只是一个思维实验,不会被用于真正的编程代码中。 - Woodrow Douglass

0

一种简单的模拟此功能的方法是将malloc()封装在一个自定义函数中,该函数:

  • 分配一个比实际需要大4个字节的缓冲区
  • 在分配的块的开头存储一些魔术数字(32位)
  • 在将指针返回给调用者之前将指针增加4个字节

通过给定指针,可以检查它是否是由malloc分配的。

当然,这并不完美:

  • 魔术数字可能是偶然存在的。在包装的free()调用中将其设置为null可以帮助。与指针进行异或等操作也可以使其更可靠。但仍然是一种启发式方法。
  • 在具有内存保护的体系结构上,检查未经过malloc的指针时,可能会触发页面错误。

尽管存在所有这些缺点,但这仍然是一种有用的技术,我在调试嵌入式系统中的某些内存损坏时使用过几次。

如果我们要用某个包装器替换malloc(),我们也可以构建一个已分配块的链接列表。更可靠,但也更复杂。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接