检查某些东西是否已被malloced

时间:2008-11-09 22:48:17

标签: c malloc

给定指向某个变量的指针..有没有办法检查它是静态还是动态分配?

8 个答案:

答案 0 :(得分:11)

引用您的评论:

  

我正在制作一个基本上摆脱结构的方法。它有一个数据成员,它指向可能或可能没有被malloced的东西..取决于哪一个,我想释放它

正确的方法是将另一个成员添加到结构中:指向释放函数的指针。

不仅仅是静态与动态分配。有几个可能的分配器,其中malloc()只是一个。

在类Unix系统上,它可能是:

  • 静态变量
  • 在堆栈上
  • 在堆栈上但动态分配(即alloca()
  • 在堆上,分配有malloc()
  • 在堆上,分配有new
  • 在堆上,在分配有new[]
  • 的数组的中间
  • 在堆上,在使用malloc()
  • 分配的结构中
  • 在堆上,在分配有new
  • 的对象的基类中
  • mmap
  • 分配
  • 使用自定义分配器
  • 分配
  • 更多选项,包括上述
  • 的几种组合和变体

在Windows上,您还有几个运行时,LocalAllocGlobalAllocHeapAlloc(可以轻松创建多个堆),依此类推。

您必须始终使用您使用的分配器的正确释放功能释放内存。因此,负责分配内存的程序部分也应该释放内存,或者必须将正确的释放函数(或它周围的包装器)传递给释放内存的代码。

您还可以通过要求指针始终使用特定分配器进行分配,或者通过自己提供分配器(以函数的形式分配内存以及可能的函数来释放它)来避免整个问题。如果您自己提供分配器,您甚至可以使用技巧(如标记指针)来允许使用静态分配(但我不会在此处详细介绍此方法)。

Raymond Chen有一篇关于它的博客文章(以Windows为中心,但各处的概念都相同):Allocating and freeing memory across module boundaries

答案 1 :(得分:2)

ACE库遍布整个地方。您可以检查他们是如何做到的。一般来说,你可能不需要在第一时间这样做......

答案 2 :(得分:2)

由于堆,堆栈和静态数据区通常占用不同的内存范围,因此可以通过对进程内存映射的深入了解来查看地址并确定它所在的分配区域。是架构和编译器特定的,因此它使您的代码移植更加困难。

答案 3 :(得分:2)

大多数libc malloc实现通过在每个返回的内存块之前存储一个头来工作,该内存块具有字段(由free()调用使用),其具有关于块大小的信息,以及“魔术”值。这个神奇的值是防止用户意外删除未被分配的指针(或释放被用户覆盖的块)。它是非常特定于系统的,因此您必须查看libc库的实现,以确切了解其中的魔术值。

一旦你知道了,你将给定指针移回指向标题,然后检查它是否有魔术值。

答案 4 :(得分:0)

你可以使用LD_PRELOAD或其他东西,像malloc调试器那样挂钩malloc()本身吗?如果是这样,您可以保留所有已分配指针的表并使用它。否则,我不确定。有没有办法获得malloc的簿记信息?

答案 5 :(得分:0)

不是标准功能。
malloc库的调试版本可能有一些功能来执行此操作。

答案 6 :(得分:0)

你可以将它的地址与你认为是静态的东西进行比较,并说如果你知道它应该来自哪个范围,那么只有当它远离它时才会进行malloced,但是如果它的范围是未知的,你就不能真正相信它这一点。

答案 7 :(得分:-1)

1。)获取您拥有的代码的地图文件。

2.)底层进程/硬件目标平台应该有一个内存映射文件,通常表示 - 内存的起始地址(堆栈,堆,global0,该块的大小,该内存块的读写属性。) p>

3.)从1中的mao文件获取对象的地址(指针变量)后,尝试查看该地址属于哪个块。你可能会有所了解。

= AD