Sandeep Singh
Sandeep Singh

Reputation: 5181

Is it possible to find the Memory Allocated to the Pointer, without searching for the malloc statement

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

Answers (3)

Employed Russian
Employed Russian

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

bdonlan
bdonlan

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

karlphillip
karlphillip

Reputation: 93410

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

Upvotes: 4

Related Questions