18

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.

joce
  • 9,624
  • 19
  • 56
  • 74
Sandeep Singh
  • 4,941
  • 8
  • 36
  • 56

3 Answers3

29

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

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
9

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.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • 6
    Or just use malloc_usable_size(), and avoid the painful contortions. – Employed Russian Apr 28 '11 at 04:00
  • „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.“ – Doesn't make sense. The question was not on determining the size in a C program but rather using a debugger. Tracking things in the program just to help debugging is not very practical in general although there are exceptions. – Pavel Šimerda Sep 16 '15 at 08:00
3

No. You have to store that information yourself when you malloc().

karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • 1
    +1 -- practically a perfect answer. Succinctly answers what he asked, *and* tells how to deal with the result. – Jerry Coffin Apr 28 '11 at 03:01
  • Thanks @Jerry. I wish someone told me that sooner, but I'll keep that in mind for next few hundred answers. – karlphillip Apr 28 '11 at 03:15
  • @karlphillip "No." - then how did the author of the accepted answer do it? Magic? –  Jun 02 '13 at 06:16
  • 3
    @H2CO3: Don't flag answers for being (partially) incorrect. That's not what flags are for. – ThiefMaster Jun 02 '13 at 07:45
  • 1
    @ThiefMaster I didn't flag it for being incorrect - I flagged it because it does not answer the question. "It's impossible" is really not an answer. –  Jun 02 '13 at 07:57
  • 5
    Yes it is. It is not possible in a way that works everywhere. – ThiefMaster Jun 02 '13 at 09:19