检查某些东西是否已被malloced
给定一个变量的指针..有没有办法检查它是静态还是动态分配?
引用您的评论:
我正在制作一个基本上摆脱结构的方法。 它有一个数据成员,它指向可能或可能没有被malloced的东西..取决于哪一个,我想释放它
正确的方法是在结构中添加另一个成员:指向释放函数的指针。
它不仅仅是静态与动态分配。 有几个可能的分配器,其中malloc()
只是一个。
在类Unix系统上,它可能是:
- 一个静态变量
- 在堆栈上
- 在堆栈上但动态分配(即
alloca()
) - 在堆上,用
malloc()
分配 - 在堆上,分配了
new
- 在堆上,在使用
new[]
分配的数组的中间 - 在堆上,在使用
malloc()
分配的结构中 - 在堆上,在用
new
分配的对象的基类中 - 用
mmap
分配 - 分配自定义分配器
- 更多选项,包括上述的几种组合和变体
在Windows上,您还有几个运行时, LocalAlloc
, GlobalAlloc
, HeapAlloc
(可以轻松创建多个堆),依此类推。
您必须始终使用您使用的分配器的正确释放function释放内存。 因此,负责分配内存的程序部分也应释放内存,或者必须将正确的释放函数(或其周围的包装器)传递给释放内存的代码。
您还可以通过要求指针始终与特定分配器一起分配,或者通过自己提供分配器(以函数的forms分配内存以及可能的函数来释放它)来避免整个问题。 如果你自己提供分配器,你甚至可以使用技巧(如标记指针)来允许一个人也使用静态分配(但我不会在这里详细介绍这种方法)。
Raymond Chen有一篇关于它的博客文章(以Windows为中心,但各处的概念都是一样的): 在模块边界分配和释放内存
ACE库遍布整个地方。 您可以检查他们是如何做到的。 一般来说,你可能不应该首先做这个,虽然……
由于堆,堆栈和静态数据区通常占用不同的存储器范围,因此可以通过对过程存储器映射的深入了解来查看地址并确定它所在的分配区域。这种技术都是架构和编译器特定的,因此它使您的代码移植更加困难。
大多数libc malloc实现通过在每个返回的内存块之前存储标头来工作,该内存块具有字段(由free()调用使用),其具有关于块大小的信息,以及“魔术”值。 这个神奇的值是为了防止用户意外删除未被分配的指针(或释放被用户覆盖的块)。 它是非常特定于系统的,因此您必须查看libc库的实现,以确切了解其中的魔术值。
一旦你知道了,你将给定指针移回指向标题,然后检查它是否有魔术值。
您可以使用LD_PRELOAD或其他东西挂接到malloc()本身,就像malloc调试器一样吗? 如果是这样,您可以保留所有已分配指针的表并使用它。 否则,我不确定。 有没有办法获得malloc的簿记信息?
不是标准function。
malloc库的调试版本可能有一些function来执行此操作。
你可以将它的地址与你认为是静态的东西进行比较,并说如果你知道它应该来自哪个范围,那么只有当它远离它时才会进行malloced,但是如果它的范围是未知的,你就不能真正相信它。
1.)获取您拥有的代码的映射文件。
2.)底层进程/硬件目标平台应该有一个内存映射文件,通常表示 – 内存的起始地址(堆栈,堆,global0,该块的大小,该内存块的读写属性)。
3.)从1中的mao文件获取对象的地址(指针变量)后,尝试查看该地址属于哪个块。 你可能会有所了解。
= AD