C中malloc分配的大小的意外输出 [英] unexpected output of size allocated by malloc in C

查看:99
本文介绍了C中malloc分配的大小的意外输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读到malloc实际上分配了(required_size + 1)个内存块,并将其存储在第一个块中,并返回了指向第二个块的指针.这种方式free()知道要释放多少内存.因此,我编写了一个小代码来输出此大小.

I have read that malloc actually allocates (required_size + 1) blocks of memory and it stores the size in the first block and the pointer to the second block is returned. This way free() knows how much memory to free. So, I wrote a small code to output this size.

int *p = (int *)malloc(100*sizeof(int));
printf("size = %d\n",p[-1]);

由于我要为100个整数分配空间,因此我希望大小为400.但是输出为409.对于50个整数的输出为209,对于1000个整数的输出为4009.有人可以解释一下为什么关闭输出吗?减少9个字节?

Since I am allocating space for 100 ints, I am expecting the size to be 400. But the output was 409. For 50 int's output was 209 and for 1000 int's output was 4009. Can someone pls explain why the output is off by 9 bytes?

推荐答案

假设实现是glibc(或类似的实现),则可以在malloc.c的注释中找到以下内容:

Assuming the implementation is glibc (or similar), the following can be found in comments in malloc.c:

Minimum overhead per allocated chunk:   4 or 8 bytes
   Each malloced chunk has a hidden word of overhead holding size
   and status information.

Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
          8-byte ptrs:  24/32 bytes (including, 4/8 overhead)

   When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
   ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
   needed; 4 (8) for a trailing size field and 8 (16) bytes for
   free list pointers. Thus, the minimum allocatable size is
   16/24/32 bytes.

这说明存在开销.

现在,对于"off by 1",标志负责.由于malloc()分配的大小(实际上)将始终是8的倍数,因此使用三个最低有效位来存储标志:

Now, for the 'off by 1', the flags are responsible for that. Since sizes (actually) allocated by malloc() will be always multiples of 8, the three least significant bits are used to store flags:

/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
#define PREV_INUSE 0x1

/* extract inuse bit of previous chunk */
#define prev_inuse(p)       ((p)->size & PREV_INUSE)


/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
#define IS_MMAPPED 0x2

/* check for mmap()'ed chunk */
#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)


/* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained
   from a non-main arena.  This is only set immediately before handing
   the chunk to the user, if necessary.  */
#define NON_MAIN_ARENA 0x4

/* check for chunk from non-main arena */
#define chunk_non_main_arena(p) ((p)->size & NON_MAIN_ARENA)

编辑:啊,我差点忘了.大小存储为size_t,而不是int,因此您应该使用该类型进行访问.

Edit: ah, and I'd almost forgot. The size is stored as size_t, not an int, so you should use that type to access it.

这篇关于C中malloc分配的大小的意外输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆