c - C 中 malloc 分配的意外大小输出

标签 c memory-management malloc heap-memory free

<分区>

我读到 malloc 实际上分配了 (required_size + 1) 个内存块,并将大小存储在第一个 block 中,并返回指向第二个 block 的指针。这样 free() 就知道要释放多少内存。所以,我写了一个小代码来输出这个大小。

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

因为我正在为 100 个整数分配空间,所以我期望大小为 400。但输出为 409。对于 50 个整数的输出为 209,对于 1000 个整数的输出为 4009。有人可以解释为什么输出关闭9个字节?

最佳答案

假设实现是 glibc(或类似的),可以在 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.

这解释了开销的存在。

现在,对于“减 1”,标志负责。由于 malloc() 分配的大小(实际上)始终是 8 的倍数,因此三个最低有效位用于存储标志:

/* 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,因此您应该使用该类型来访问它。

关于c - C 中 malloc 分配的意外大小输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11976414/

相关文章:

c++ - 这个geeksforgeeks trie实现是否存在内存泄漏问题?

c - 如何将二维数组发送到函数?

c - 理解 C 中的二维数组

c++ - 使用算术符号来遍历字符串

c - 如何从文本文件中读取和保存数据?

c - foo(x++, y)::x 是否总是在作为参数发送后递增?

c - 使用数组在 C 中实现堆栈

c - 多个线程在没有锁的情况下递增共享变量但返回 "unexpected"输出

c++ - 堆栈上的可变大小对象

c++ - 进程终止时是否回收了内存?