1

我想找到 malloc 使用的块结构

源代码说它看起来像这样:

struct malloc_chunk {

  INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */
  INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */

  struct malloc_chunk* fd;         /* double links -- used only if free. */
  struct malloc_chunk* bk;

  /* Only used for large blocks: pointer to next larger size.  */
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
}

但是此代码执行无效读取:

int main()
{
  struct malloc_chunk *chunk;
  void                *ptr;

  ptr = malloc(10);
  chunk = ptr - sizeof(struct malloc_chunk);
  printf("%p\n", chunk->fd);
}

然后我试图用这个找到块大小:

int main()
{
   void  *ptr1;
   void  *ptr2;

   ptr1 = malloc(10);
   ptr2 = malloc(10);

   printf("%d\n", ptr2 - ptr1 - 10);
}

我得到了尺寸:

  • 10 : 22
  • 500 : 12
  • 31 : 31

我怎样才能得到 malloc 的元数据?

4

1 回答 1

4

如果您在malloc_chunk声明后立即查看评论,您将看到以下内容:

/*
malloc_chunk details:

(The following includes lightly edited explanations by Colin Plumb.)

Chunks of memory are maintained using a `boundary tag' method as
described in e.g., Knuth or Standish. (See the paper by Paul
Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
survey of such techniques.) Sizes of free chunks are stored both
in the front of each chunk and at the end. This makes
consolidating fragmented chunks into bigger chunks very fast. The
size fields also hold bits representing whether chunks are free or
in use.

An allocated chunk looks like this:


    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                                                |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            ...

*/

注意它说的地方"User data starts here..."——在处理分配的内存块时,指向用户内存块的指针从结构内部malloc_chunk开始。

内存分配器的实现(尤其是生产实现)经常使用在大多数代码中被认为是非常糟糕的编码实践的 hack。他们这样做是因为内存分配例程被大量使用,而时间和空间上的小幅收益通常会导致程序性能的巨大差异。

于 2014-02-03T19:15:09.090 回答