La forma más fácil de hacerlo es mantener una lista vinculada de bloques libres. En malloc
, si la lista no está vacía, busca un bloque lo suficientemente grande como para satisfacer la solicitud y devolverla. Si la lista está vacía o si no se puede encontrar dicho bloque, llame al sbrk
para asignar parte de la memoria del sistema operativo. en free
, simplemente agrega el fragmento de memoria a la lista de bloques libres. Como bonificación, puede intentar combinar un bloque libre contiguo, y puede cambiar la política para elegir el bloque a devolver (primer ajuste, mejor ajuste, ...). También puede elegir dividir el bloque si es más grande que la solicitud.
Algunos implementación de ejemplo (que no se ha probado, y, obviamente, no es seguro para subprocesos, utilice a su propio riesgo):
typedef struct free_block {
size_t size;
struct free_block* next;
} free_block;
static free_block free_block_list_head = { 0, 0 };
static const size_t overhead = sizeof(size_t);
static const size_t align_to = 16;
void* malloc(size_t size) {
size = (size + sizeof(size_t) + (align_to - 1)) & ~ (align_to - 1);
free_block* block = free_block_list_head.next;
free_block** head = &(free_block_list_head.next);
while (block != 0) {
if (block->size >= size) {
*head = block->next;
return ((char*)block) + sizeof(size_t);
}
head = &(block->next);
block = block->next;
}
block = (free_block*)sbrk(size);
block->size = size;
return ((char*)block) + sizeof(size_t);
}
void free(void* ptr) {
free_block* block = (free_block*)(((char*)ptr) - sizeof(size_t));
block->next = free_block_list_head.next;
free_block_list_head.next = block;
}
Nota: (n + align_to - 1) & ~ (align_to - 1)
es un truco para redondear n
al múltiplo más cercano de align_to
que es más grande que n
. Esto solo funciona cuando align_to
tiene una potencia de dos y depende de la representación binaria de los números.
Cuando align_to
es una potencia de dos, que sólo tiene un conjunto de bits, y por lo tanto align_to - 1
tiene todos los conjuntos de bits más bajas (es decir. align_to
es de la forma 000 ... 010 ... 0, y es de align_to - 1
el formulario 000...001...1
). Esto significa que ~ (align_to - 1)
tiene todo el bit alto establecido, y el bit bajo no está configurado (es decir, tiene el formato 111...110...0
).Así x & ~ (align_to - 1)
se pone a cero todos los bits bajos de x
y se redondea al múltiplo más próximo de align_to
.
Por último, la adición de align_to - 1
a size
asegurar que rodeo al múltiplo más cercano de align_to
(a menos size
ya es un múltiplo de align_to
en cuyo caso queremos obtener size
).
Hay una buena valoración crítica sobre dlmalloc aquí: http://g.oswego.edu/dl/html/malloc.html – ninjalj