有没有可能找到分配给指针的内存,而不搜索malloc语句

ttp71kqs  于 2023-04-05  发布在  其他
关注(0)|答案(3)|浏览(107)

假设我给函数foo中的某个指针分配了内存:

void foo()
{    
    // ...  
    int *ptr = malloc(20*sizeof(int));  

    bar (ptr);
}

foo(),我把这个指针传递给bar(),假设从bar()传递给另一个函数。
现在,在某个时间点,我想检查:分配给指针的内存量。
有没有可能的方法,不搜索语句:

int *ptr = malloc(20*sizeof(int));

用GDB计算出指针分配了多少内存?
谢谢。

xzv2uavs

xzv2uavs1#

答案是:看情况而定。
许多系统都提供msize() [1]、malloc_usable_size() [2]或类似的函数。如果您在这样的系统上,(gdb) print malloc_usable_size(ptr)就是您所需要的。

2023年更新:

msize()文档已经死了,但是_msize()仍然可用。
[1][http://msdn.microsoft.com/en-us/library/z2s077bc(v=vs.80).aspx](http://msdn.microsoft.com/en-us/library/z2s077bc(v=vs.80).aspx)
[2][http://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.malloc.html](http://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.malloc.html)

whitzsjs

whitzsjs2#

一般来说,C不提供获取已分配内存块大小的方法,你需要自己记录分配了多少内存。

  • 但是 *,在一些C库上,有一个函数可以获取内存块的可用大小-malloc_usable_size(在Linux系统上可以在<malloc.h>中找到,没有手册页)。注意,这并不适用于所有的库,并且可能报告一个大于您请求的值。请仅在调试时使用它。

为了完整起见,我最初的答案,在@Employed Russian指出malloc_usable_size之前,深入到低级堆元数据:

  • 但是 *,您可以手动提取它。但是,请注意,这一切都取决于您的操作系统,CPU架构和C库。我假设您使用eglibc 2.12.1;您的结果可能会有所不同其他任何地方。
    警告:说真的,除了在gdb中调试,不要使用这个。真的,我是认真的。

glibc内存分配器像这样存储内存块(来自malloc/malloc.c中的文档注解):

chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of previous chunk, if allocated            | |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of chunk, in bytes                       |M|P|
      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             User data starts here...                          .
            .                                                               .
            .             (malloc_usable_size() bytes)                      .
            .                                                               |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of chunk                                     |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

你的数据在这里是'mem',chunk的大小包括header。P标志表示前一个chunk数据是否有效,M表示这是一个mmapMap(对于大的mallocs)。所有这些都不是太重要;重要的是,大小在你的记忆之前存在一个指针大小的增量;你只需要屏蔽掉那些标志并减去头部大小:

Breakpoint 1, main () at test.c:8
8               char *a = malloc(32);
(gdb) n
10              free(a);
(gdb) print (*((unsigned long long*)a - 1) & ~3) - sizeof(unsigned long long)*2
$14 = 32

警告:实际分配的大小可能比您要求的大。不要自作聪明地使用多余的。在开始时询问您需要多少。
警告2:这只适用于glibc,而且只适用于特定版本的glibc,因此可能会在没有任何警告的情况下随时崩溃。请勿在实际代码中使用此内容;只有当你已经用尽了所有其他的选项时才能调试。你的代码需要自己跟踪它的缓冲区大小。

yh2wf1be

yh2wf1be3#

malloc()时需要自行存储。

相关问题