Reputation: 5181
Suppose I have allocated memory to some pointer in a function foo
:
void foo()
{
// ...
int *ptr = malloc(20*sizeof(int));
bar (ptr);
}
From foo()
, I pass this pointer to bar()
and let's say from bar()
to another function.
Now, at some point of time, I want to check: How much memory was allocated to the pointer.
Is there any possible way, without searching for the statement:
int *ptr = malloc(20*sizeof(int));
to figure out how much memory is allocated to the pointer, using GDB?
Thanks.
Upvotes: 18
Views: 16799
Reputation: 213516
The answer is: it depends.
Many systems provide msize()
[1], malloc_usable_size()
[2], or similar function. If you are on such a system, (gdb) print malloc_usable_size(ptr)
is all you need.
2023 Update:
msize()
documentation is dead, but _msize() is still available.
[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
Upvotes: 30
Reputation: 231133
In general, no. C doesn't provide a way to get the size of an allocated block of memory. You need to keep track of how much memory you allocated yourself.
BUT, on some C libraries, there is a function to get the usable size of a block of memory - malloc_usable_size (found in <malloc.h>
on Linux systems, with no manpage). Note that this does not work on all libcs, and may report a value larger than you requested. Please, use it only for debugging.
For completeness, my original answer, which dives into the low-level heap metadata, prior to @Employed Russian pointing out malloc_usable_size
:
BUT, you may be able to extract this manually. Note, however, that this all can vary depending on your OS, CPU architecture, and C library. I will assume you're using eglibc 2.12.1; your results may vary anywhere else.
WARNING: Seriously, DO NOT use this except for debugging in gdb. Really. I mean it.
The glibc memory allocator stores chunks of memory like this (out of a doc comment in 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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Your data is at 'mem' here, and the size of chunk includes the header. The P flag indicates whether the previous-chunk data is valid, and M indicates this is a mmap mapping (for large mallocs). All of that isn't too important; what's important is that the size lives one pointer-sized increment before your memory; you just have to mask out those flags and subtract the header size:
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
Caveat: The actually allocated size may be larger than you requested. Don't try to get smart and use the excess. Ask for how much you need at the start.
Caveat 2: This only works with glibc. And it only works with certain versions of glibc. and thus may break at any moment without any warning. I can't stress this enough; DO NOT use this in your actual code; only for debugging when you have exhausted every other option. Your code needs to keep track of its buffer sizes on its own.
Upvotes: 9
Reputation: 93410
No. You have to store that information yourself when you malloc()
.
Upvotes: 4