Un asignador bump sencillo
Asigne memoria linealmente
Un asignador bump sencillo es una lección gratuita de C Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C Academy incluye 4 lecciones en total.
La idea del asignador bump
Un asignador bump (o de arena) es el diseño más sencillo. Se mantiene un búfer grande y un único desplazamiento. Cada asignación simplemente devuelve el desplazamiento actual y después lo «incrementa» según el tamaño solicitado.
No hay metadatos por bloque ni búsquedas. Asignar consiste esencialmente en una suma de punteros, lo que lo hace extremadamente rápido.
Un búfer estático de respaldo
Para este ejemplo autónomo, respaldamos el asignador con una matriz estática en lugar del montón del sistema operativo. Se compila y se ejecuta en cualquier entorno, sin sbrk ni mmap.
La matriz nos proporciona un conjunto fijo de bytes que podemos dividir.
#define POOL_SIZE 1024
static unsigned char pool[POOL_SIZE];
static size_t offset = 0;La función bump principal
La asignación comprueba si queda espacio suficiente, registra el inicio, avanza el desplazamiento y devuelve el puntero inicial. Si la solicitud desbordaría el conjunto disponible, devuelve NULL.
Esta comprobación de desbordamiento es la única medida de seguridad que proporciona el asignador bump.
void *bump_alloc(size_t size) {
if (offset + size > POOL_SIZE)
return NULL; /* out of pool */
void *p = &pool[offset];
offset += size;
return p;
}Un asignador bump completo y ejecutable
Aquí tiene un programa completo. Asigna dos enteros y una cadena corta del conjunto disponible y los imprime, demostrando que el asignador funciona.
Observe cuánto menos código requiere en comparación con un malloc real.
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#define POOL_SIZE 1024
static unsigned char pool[POOL_SIZE];
static size_t offset = 0;
void *bump_alloc(size_t size) {
if (offset + size > POOL_SIZE) return NULL;
void *p = &pool[offset];
offset += size;
return p;
}
int main(void) {
int *a = bump_alloc(sizeof(int));
int *b = bump_alloc(sizeof(int));
char *s = bump_alloc(6);
*a = 10; *b = 32;
strcpy(s, "hi");
printf("%d %d %s\n", *a, *b, s);
printf("used = %zu\n", offset);
return 0;
}Sin liberación individual
El inconveniente es que un asignador bump no puede liberar una asignación individual. Como no hay metadatos, no sabe dónde termina un bloque y comienza el siguiente para poder reutilizarlo.
Solo puede restablecer toda la arena de una vez, estableciendo de nuevo el desplazamiento en cero.
void bump_reset(void) {
offset = 0; /* frees everything at once */
}Por qué es útil restablecer la arena
Este modelo de todo o nada es perfecto para el trabajo por fases: asigne muchos objetos durante una solicitud o un fotograma y, después, restablezca la arena cuando termine la fase.
Los motores de videojuegos y los compiladores utilizan mucho las arenas porque restablecerlas cuesta O(1) y evita tener que controlar miles de liberaciones individuales.
/* Per-frame pattern */
for (int frame = 0; frame < 3; frame++) {
void *tmp = bump_alloc(128);
/* ... use tmp this frame ... */
bump_reset(); /* reclaim instantly */
}Seguimiento del espacio restante
Es útil exponer cuánto espacio queda. Es simplemente el tamaño del conjunto menos el desplazamiento actual.
Los llamadores pueden usar este dato para decidir si deben volcar los datos o ampliar el conjunto antes de solicitar más espacio.
size_t bump_remaining(void) {
return POOL_SIZE - offset;
}Una demostración ejecutable de reinicio
Este programa llena parte del conjunto, muestra el uso, lo reinicia y muestra cómo el desplazamiento vuelve a cero, de modo que el espacio se puede reutilizar.
#include <stdio.h>
#include <stddef.h>
#define POOL_SIZE 256
static unsigned char pool[POOL_SIZE];
static size_t offset = 0;
void *bump_alloc(size_t s){ if(offset+s>POOL_SIZE) return NULL; void *p=&pool[offset]; offset+=s; return p; }
void bump_reset(void){ offset = 0; }
int main(void) {
bump_alloc(100);
printf("after alloc: used=%zu\n", offset);
bump_reset();
printf("after reset: used=%zu\n", offset);
return 0;
}Alineación en un asignador bump
Incrementar byte a byte sin más puede devolver punteros desalineados. Para evitarlo, redondee el desplazamiento hacia arriba hasta un límite de alineación antes de devolver un puntero.
Analizaremos las matemáticas en detalle más adelante, pero la alineación es especialmente importante en un asignador bump porque, de lo contrario, no hay relleno.
static size_t align_up(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1); /* a must be power of 2 */
}Un asignador bump alineado
Al combinar las piezas, alineamos el desplazamiento antes de cada asignación. Esto garantiza que todos los punteros devueltos sean adecuados para cualquier tipo común.
El coste es una pequeña fragmentación interna causada por los bytes de relleno.
#define ALIGN 16
void *bump_aligned(size_t size) {
offset = align_up(offset, ALIGN);
if (offset + size > POOL_SIZE) return NULL;
void *p = &pool[offset];
offset += size;
return p;
}Ventajas y limitaciones
Los asignadores bump son imbatiblemente rápidos y sencillos, y no tienen sobrecoste por objeto. Son ideales cuando los objetos comparten ciclo de vida.
Su desventaja es la falta de liberación detallada. Cuando los ciclos de vida difieren, necesita el diseño de lista libre que se explica en la siguiente lección.
Comprobación rápida
Considere cómo un asignador bump recupera la memoria.
Resumen
Un asignador bump entrega memoria avanzando un único desplazamiento por un búfer, por lo que asignar resulta tan barato como sumar a un puntero.
Renuncia a la liberación individual a cambio de velocidad y sencillez, y solo recupera la memoria mediante un reinicio completo. Alinee el desplazamiento para mantener válidos los punteros devueltos para todos los tipos.
Preguntas frecuentes
¿La lección «Un asignador bump sencillo» es gratis?
Sí — el texto completo de «Un asignador bump sencillo» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C Academy, actualiza a CoddyKit PRO. El curso de C Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Un asignador bump sencillo»?
Asigne memoria linealmente Practicas C Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C Academy?
No se requiere experiencia previa. C Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Un asignador bump sencillo»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C Academy?
Sí. Cada lección de C Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Cómo funciona malloc
- Un asignador bump sencillo
- Listas libres y reutilización
- Alineación y división