是否可以找到分配给指针的内存,而无需搜索malloc语句

时间:2011-04-28 02:54:36

标签: c gdb

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

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

    bar (ptr);
}  

foo()开始,我将此指针传递给bar(),然后从bar()转到另一个函数。

现在,在某些时候,我想检查一下:为指针分配了多少内存。

有没有可能的方法,没有搜索声明:

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

使用GDB计算指针分配了多少内存?

感谢。

3 个答案:

答案 0 :(得分:24)

答案是:取决于

许多系统提供msize() [1],malloc_usable_size() [2]或类似功能。如果您使用的是此系统,则只需(gdb) print malloc_usable_size(ptr)即可。

[1] 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

答案 1 :(得分:9)

一般来说,没有。 C没有提供获取已分配内存块大小的方法。您需要跟踪自己分配的内存量。

BUT ,在某些C库中,有一个函数来获取内存块的可用大小 - malloc_usable_size(在Linux系统的<malloc.h>中找到,没有手册页)。请注意,这不适用于所有libcs​​,并且可能会报告大于您请求的值。请将其用于调试。

为了完整性,我的原始答案潜入了低级别的堆元数据,在@Employed Russian指出malloc_usable_size之前:

但是,您可以手动提取。但请注意,这一切都可能因您的操作系统,CPU架构和C库而异。我假设你正在使用eglibc 2.12.1;您的结果可能会随处变化。

警告:严重的是,除了在gdb中调试外,请不要使用它。真。我的意思是。

glibc内存分配器存储这样的内存块(来自malloc/malloc.c中的doc注释):

    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”,并且块的大小包括标题。 P标志指示前一块数据是否有效,M表示这是mmap映射(对于大型malloc)。所有这一切都不太重要;重要的是,大小在你的记忆之前存在一个指针大小的增量;你只需要掩盖那些标志并减去标题大小:

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。因此可能在任何时候都没有任何警告而破裂。我不能强调这一点; 不要在您的实际代码中使用它;只有在你用完所有其他选项时进行调试。您的代码需要自己跟踪其缓冲区大小。

答案 2 :(得分:3)

即可。您必须在malloc()时自行存储该信息。