假设我已经为函数foo
中的某个指针分配了内存:
void foo()
{
// ...
int *ptr = malloc(20*sizeof(int));
bar (ptr);
}
从foo()
开始,我将此指针传递给bar()
,然后从bar()
转到另一个函数。
现在,在某些时候,我想检查一下:为指针分配了多少内存。
有没有可能的方法,没有搜索声明:
int *ptr = malloc(20*sizeof(int));
使用GDB计算指针分配了多少内存?
感谢。
答案 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()
时自行存储该信息。