简体   繁体   English

malloc 和 free 的内存管理

[英]Memory management by malloc and free

I am currently learning how memory is managed by malloc and free, and I don't understand why when I want to malloc 1 byte, malloc will allocate 32 bytes for the chunk ?我目前正在学习 malloc 和 free 是如何管理内存的,我不明白为什么当我想要 malloc 1 个字节时,malloc 会为块分配 32 个字节? For me, it should allocate 16 bytes for metadata (size of previous chunk and next chunk) and 1 byte for the data...对我来说,它应该为元数据(前一个块和下一个块的大小)分配 16 个字节,为数据分配 1 个字节......

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/**                                                                                            
 * pmem - print mem                                                                            
 * @p: memory address to start printing from                                                   
 * @bytes: number of bytes to print                                                            
 *                                                                                             
 * Return: nothing                                                                             
 */
void pmem(void *p, unsigned int bytes)
{
    unsigned char *ptr;
    unsigned int i;

    ptr = (unsigned char *)p;
    for (i = 0; i < bytes; i++)
    {
        if (i != 0)
        {
            printf(" ");
        }
        printf("%02x", *(ptr + i));
    }
    printf("\n");
}

/**
 * main - moving the program break
 *
 * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
 */
int main(void)
{
    void *p;
    size_t size_of_the_chunk;
    char prev_used;

    p = malloc(1);
    printf("%p\n", p);
    pmem((char *)p - 0x10, 0x10);
    size_of_the_chunk = *((size_t *)((char *)p - 8));
    prev_used = size_of_the_chunk & 1;
    size_of_the_chunk -= prev_used;
    printf("chunk size = %li bytes\n", size_of_the_chunk);
    return (EXIT_SUCCESS);
}

That's the result :这就是结果:

0x13bf010 0x13bf010

00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00

chunk size = 32 bytes块大小 = 32 字节

malloc is required to return pointers that are sufficiently aligned to store any type of data, even types of data that can't fit into the space allocated. malloc需要返回足够对齐的指针以存储任何类型的数据,甚至是无法放入分配空间的数据类型。 That means that if _Alignof(max_align_t) == 32 on your system, malloc(1) has to return only pointers that are multiples of 32, even if you ask for less space than that.这意味着如果_Alignof(max_align_t) == 32在您的系统上, malloc(1)必须仅返回 32 的倍数的指针,即使您要求的空间小于该值。 An easy way for the implementation to do this is for it to round up each allocation to a multiple of 32 in its internal bookkeeping data, which appears to be what you are looking at.实现执行此操作的一种简单方法是在其内部簿记数据中将每个分配舍入为 32 的倍数,这似乎就是您正在查看的内容。

However, the C standard specifically forbids you to access memory even a single byte beyond the end of the amount of space you asked for.但是,C 标准特别禁止您访问超出您要求的空间量末尾的单个字节的内存。 It also specifically forbids you to access malloc 's internal bookkeeping data.它还特别禁止您访问malloc的内部簿记数据。 If you run your program under a memory access validator like valgrind or ASan it will crash.如果您在内存访问验证器(如valgrind或 ASan)下运行您的程序,它将崩溃。

I want to malloc 1 byte, malloc will allocate 32 bytes for the chunk ?我想 malloc 1 个字节,malloc 会为块分配 32 个字节吗? For me, it should allocate 16 bytes for metadata (size of previous chunk and next chunk) and 1 byte for the data...对我来说,它应该为元数据(前一个块和下一个块的大小)分配 16 个字节,为数据分配 1 个字节......

Then you need to write your own version of the malloc .然后您需要编写自己的malloc版本。

Standard does not say how this allocation should look like, if there is any additional data, or how much memory will be allocated.标准没有说明这种分配应该是什么样子,是否有任何额外的数据,或者将分配多少内存。

There are many circumstances which have to be taken into the consideration, not only the "metadata".有许多情况需要考虑,而不仅仅是“元数据”。 For sure author of the implementation had something in mind when decided how to implement 'malloc'在决定如何实现“malloc”时,实现的作者肯定有一些想法

In short, the C library memory management is free to allocate as much memory as it considers useful.简而言之,C 库内存管理可以自由分配它认为有用的内存。 Maybe for the sake of simplicity, it only allocates in multiples of 32 bytes.也许为了简单起见,它仅以 32 字节的倍数进行分配。 Then, obviously, 32 byte is the minimum.那么,显然,32 字节是最小值。

Other allocators may use other strategies.其他分配器可能会使用其他策略。

For me, it should allocate 16 bytes for metadata (size of previous chunk and next chunk)对我来说,它应该为元数据分配 16 个字节(上一个块和下一个块的大小)

No, you can't state something like that.不,你不能这样说。 It should allocate at least one byte, that's all.它应该至少分配一个字节,仅此而已。 You are supposing that a given allocation strategy/implementation works in a very specific manner, but you can't in general.您假设给定的分配策略/实现以非常具体的方式工作,但一般情况下您不能。 There is no standard that specifies the way block of free/allocated chunks of memory are managed.没有标准指定管理空闲/分配的内存块的方式。 This may be described in the documentation of the allocation library you use.这可能在您使用的分配库的文档中有所描述。

and 1 byte for the data和 1 个字节的数据

Again, at least.再次,至少。 Most of allocators prefer to allocate a bunch of bytes (32 or 64 is common).大多数分配器更喜欢分配一堆字节(32 或 64 是常见的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM