Управление памятью по Mallo c и бесплатно - PullRequest
1 голос
/ 07 февраля 2020

В настоящее время я изучаю, как память управляется mallo c и свободна, и я не понимаю, почему, когда я хочу mallo c 1 байт, mallo c выделит 32 байта для фрагмента? Для меня это должно выделить 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);
}

Вот результат:

0x13bf010

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

размер куска = 32 байта

Ответы [ 4 ]

5 голосов
/ 07 февраля 2020

malloc требуется для возврата указателей, которые достаточно выровнены для хранения данных любого типа, даже типов данных, которые не могут поместиться в выделенном пространстве. Это означает, что если _Alignof(max_align_t) == 32 в вашей системе, malloc(1) должен возвращать только указатели, кратные 32, даже если вы запрашиваете меньше места, чем это. Для реализации простой способ сделать это состоит в том, чтобы округлить каждое распределение до значения, кратного 32, в своих внутренних бухгалтерских данных, что, по-видимому, является тем, на что вы смотрите.

Однако C Стандарт специально запрещает вам доступ к памяти даже на один байт за пределами требуемого объема пространства. Он также специально запрещает вам доступ к внутренним бухгалтерским данным malloc. Если вы запустите свою программу под валидатором доступа к памяти, таким как valgrind или ASan, она вызовет sh.

2 голосов
/ 07 февраля 2020

Я хочу, чтобы mallo c 1 байт, mallo c выделит 32 байта для фрагмента? Для меня это должно выделить 16 байтов для метаданных (размер предыдущего чанка и следующего чанка) и 1 байт для данных ...

Затем вам нужно написать свою собственную версию malloc ,

Стандарт не говорит, как должно выглядеть это распределение, если есть какие-либо дополнительные данные или сколько памяти будет выделено.

Есть много обстоятельств, которые должны быть приняты во внимание, не только "метаданные". Наверняка автор реализации что-то имел в виду, когда решил, как реализовать 'mallo c'

1 голос
/ 07 февраля 2020

Короче говоря, управление памятью библиотеки C может свободно выделять столько памяти, сколько считает полезным. Может быть, для простоты он выделяется только в 32 байта. Тогда, очевидно, 32 байта - это минимум.

Другие распределители могут использовать другие стратегии.

0 голосов
/ 07 февраля 2020

Для меня это должно выделить 16 байтов для метаданных (размер предыдущего чанка и следующего чанка)

Нет, вы не можете заявить что-то подобное. Следует выделить хотя бы один байт, вот и все. Вы предполагаете, что данная стратегия / реализация распределения работает очень специфично c, но вы не можете вообще. Не существует стандарта, определяющего способ управления блоком свободных / выделенных фрагментов памяти. Это может быть описано в документации используемой вами библиотеки выделения.

и 1 байт для данных

Опять, по крайней мере. Большинство распределителей предпочитают выделять группу байтов (обычно 32 или 64).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...