假设我已经为函数中的某个指针分配了内存foo:
void foo()
{
// ...
int *ptr = malloc(20*sizeof(int));
bar (ptr);
}
Run Code Online (Sandbox Code Playgroud)
从foo(),我将这个指针传递给另一个函数bar(),让我们说bar().
现在,在某个时间点,我想检查:指针分配了多少内存.
有没有可能的方法,没有搜索声明:
int *ptr = malloc(20*sizeof(int));
Run Code Online (Sandbox Code Playgroud)
使用GDB计算出为指针分配了多少内存?
谢谢.
Emp*_*ian 25
答案是:这取决于.
许多系统提供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
一般来说,没有.C没有提供获取已分配内存块大小的方法.您需要跟踪自己分配的内存量.
但是,在某些C库中,有一个函数可以获得内存块的可用大小 - malloc_usable_size(在<malloc.h>Linux系统中找到,没有联机帮助页).请注意,这不适用于所有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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)
您的数据在此处为"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
Run Code Online (Sandbox Code Playgroud)
警告:实际分配的大小可能比您要求的大.不要试图变得聪明并使用多余的东西.询问您一开始需要多少.
警告2:这只适用于glibc.它只适用于某些版本的glibc.因此可能在任何时候都没有任何警告而破裂.我不能强调这一点; 不要在实际代码中使用它; 只有在你用完所有其他选项时进行调试.您的代码需要自己跟踪其缓冲区大小.