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

前端 未结 3 1912
执笔经年
执笔经年 2020-12-05 03:25

Suppose I have allocated memory to some pointer in a function foo:

void foo()
{    
    // ...  
    int *ptr = malloc(20*sizeof(int));  

    b         


        
相关标签:
3条回答
  • 2020-12-05 03:44

    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.

    0 讨论(0)
  • 2020-12-05 03:50

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

    0 讨论(0)
  • 2020-12-05 04:08

    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.

    [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

    0 讨论(0)
提交回复
热议问题