Escrevendo um alocador de memória
Trecho para um alocador de memória em C
Alocadores de memória 101 - Escreva um alocador de memória simples
void * malloc ( size_t size );
void free ( void * ptr );
Block * merge_blocks ( Block * block );
// the above three will be implemented first later calloc and realloc Defina a estrutura de dados : você precisará de uma estrutura de dados para acompanhar o status de tamanho e alocação de cada bloco. Isso pode ser uma estrutura simples com tamanho e um sinalizador indicando se o bloco está livre ou não.
Inicialize a pilha : quando o seu programa começar, você precisará reservar um pedaço de memória para atuar como sua pilha. Isso pode ser feito usando a chamada do sistema mmap() .
Implementar malloc() : Esta função deve encontrar um bloco livre que seja grande o suficiente para satisfazer a solicitação. Se não existir esse bloco, ele deve aumentar o tamanho da pilha. Depois que um bloco adequado é encontrado, ele deve ser marcado como alocado e seu endereço retornado.
Implementar free() : Esta função deve levar um ponteiro para um bloco de memória, marcar -o como livre e potencialmente reduzir o tamanho da pilha se o bloco liberado estiver no final.
Implementar realloc() : esta função deve redimensionar um bloco alocado. Isso pode envolver encontrar um novo bloco e copiar os dados antigos.
Fragmentação de manuseio : Com o tempo, a pilha pode se fragmentar com blocos livres espalhados por toda parte. Você pode implementar uma estratégia para desfragmentar a pilha, como bloqueios livres adjacentes coalescentes.
No contexto de um alocador de heap, "blocos" se referem a pedaços de memória dentro da pilha. Eis por que você precisa deles e como eles funcionam:
Por que blocos? : Quando você está gerenciando memória, é útil dividi -la em pedaços gerenciáveis ou "blocos". Cada bloco pode ser alocado e desalocado de forma independente. Isso permite o uso eficiente da memória, pois você pode alocar exatamente o máximo de memória necessário, nem mais nem menos.
Estrutura do bloco : Cada bloco normalmente contém metadados sobre o bloco (como seu tamanho e se é gratuito ou alocado) e os dados reais armazenados no bloco. Os metadados são usados pelo alocador para gerenciar a memória.
Alocação : quando você liga malloc() , o alocador procura um bloco livre grande o suficiente para manter a quantidade solicitada de dados. Se encontrar um, marca esse bloqueio como alocado e retorna um ponteiro para a parte dos dados do bloco.
Desalocação : quando você chama free() , o alocador marca o bloco como gratuito, disponibilizando -o para alocações futuras. Se o bloco liberado estiver no final da pilha, o alocador também poderá reduzir o tamanho da pilha para liberar a memória.
Fragmentação : Com o tempo, à medida que os blocos são alocados e desalocados, a pilha pode se fragmentar. Isso significa que a memória livre é dividida em pequenos blocos não contíguos. Isso pode dificultar a localização de um bloco grande o suficiente para uma chamada malloc() , mesmo que haja uma memória total total suficiente. Para lidar com isso, os alocadores geralmente incluem a lógica para desfragmentar a pilha, como coalescantes blocos livres adjacentes.