Progear
Progear

Reputation: 167

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 ? For me, it should allocate 16 bytes for metadata (size of previous chunk and next chunk) and 1 byte for the data...

#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

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

chunk size = 32 bytes

Upvotes: 1

Views: 277

Answers (4)

0___________
0___________

Reputation: 67721

I want to malloc 1 byte, malloc will allocate 32 bytes for the chunk ? For me, it should allocate 16 bytes for metadata (size of previous chunk and next chunk) and 1 byte for the data...

Then you need to write your own version of the 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'

Upvotes: 2

Jean-Baptiste Yun&#232;s
Jean-Baptiste Yun&#232;s

Reputation: 36431

For me, it should allocate 16 bytes for metadata (size of previous chunk and next chunk)

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

Again, at least. Most of allocators prefer to allocate a bunch of bytes (32 or 64 is common).

Upvotes: 0

glglgl
glglgl

Reputation: 91099

In short, the C library memory management is free to allocate as much memory as it considers useful. Maybe for the sake of simplicity, it only allocates in multiples of 32 bytes. Then, obviously, 32 byte is the minimum.

Other allocators may use other strategies.

Upvotes: 1

zwol
zwol

Reputation: 140748

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

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. It also specifically forbids you to access malloc's internal bookkeeping data. If you run your program under a memory access validator like valgrind or ASan it will crash.

Upvotes: 6

Related Questions