Alignement et découpage
Rendez les blocs utilisables et ordonnés.
Alignement et découpage est une leçon C Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C Academy comprend 4 leçons au total.
Pourquoi l’alignement est important
Chaque type a une exigence d’alignement : son adresse doit être un multiple d’une certaine puissance de deux. Un double nécessite généralement un alignement sur 8 octets.
Comme malloc ne sait pas ce que vous allez stocker, il doit renvoyer des pointeurs alignés pour le type le plus exigeant, généralement sur 16 octets dans les systèmes 64 bits.
#include <stdalign.h>
/* the strictest fundamental alignment */
size_t strict = alignof(max_align_t); /* often 16 */L’astuce align_up
Arrondir une taille vers le haut jusqu’au multiple suivant d’un alignement qui est une puissance de deux est une astuce classique sur les bits : ajoutez a - 1, puis masquez les bits de poids faible.
Cela ne fonctionne que lorsque a est une puissance de deux, ce qui est le cas de tous les alignements réels.
static size_t align_up(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1);
}
/* align_up(13, 8) == 16, align_up(16, 8) == 16 */Vérifier les calculs en pratique
Vérifions align_up avec un programme exécutable. Il arrondit plusieurs tailles sur des frontières de 8 et de 16 octets, puis affiche les résultats.
#include <stdio.h>
#include <stddef.h>
static size_t align_up(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1);
}
int main(void) {
printf("%zu\n", align_up(13, 8)); /* 16 */
printf("%zu\n", align_up(16, 8)); /* 16 */
printf("%zu\n", align_up(1, 16)); /* 16 */
printf("%zu\n", align_up(33, 16)); /* 48 */
return 0;
}Alignement des tailles demandées
Dans l’allocateur, la première étape de chaque demande consiste à arrondir la taille demandée jusqu’à l’alignement. Cela garantit que le prochain block commence lui aussi avec le bon alignement.
Les octets de remplissage constituent une fragmentation interne : c’est le prix d’un alignement universel.
#define ALIGN 16
void *my_alloc(size_t size) {
size = align_up(size, ALIGN);
/* now find a block of this aligned size */
/* ... */
return NULL;
}Le problème de la réutilisation de blocs entiers
Dans la leçon précédente, nous renvoyions un block libre entier, même pour les petites demandes. Un block libre de 4000 octets remis pour une demande de 16 octets gaspille tout le reste.
Le découpage sépare le block en la partie que nous utilisons et un reste qui demeure libre.
Découpage d’un block
Si un block choisi est beaucoup plus grand que nécessaire, nous plaçons un nouvel en-tête à la fin de la région demandée. Le reste devient un block libre plus petit dans la liste.
Nous ne découpons que lorsque le reste est suffisamment grand pour contenir un en-tête et une certaine charge utile ; sinon, le fragment est inutile.
void split(block_t *b, size_t size) {
size_t rem = b->size - size;
if (rem < sizeof(block_t) + ALIGN) return; /* too small */
block_t *nb = (block_t *)((char *)(b + 1) + size);
nb->size = rem - sizeof(block_t);
nb->free = 1;
nb->next = b->next;
b->size = size;
b->next = nb;
}Allouer, aligner, découper
Le parcours complet d’allocation aligne maintenant la taille, trouve une adéquation, sépare tout reste suffisamment grand et marque le block comme utilisé.
Les blocs ont ainsi une taille adaptée et l’espace libre restant demeure utilisable.
void *my_alloc(size_t size) {
size = align_up(size, ALIGN);
block_t *b = first_fit(size);
if (!b) return NULL;
split(b, size);
b->free = 0;
return (void *)(b + 1);
}Maintenir la zone mémoire elle-même alignée
Pour garantir la correction, l’adresse de début de la zone mémoire et la taille de l’en-tête doivent également respecter l’alignement, afin que chaque charge utile tombe sur une frontière.
L’utilisation de alignas sur le tampon statique garantit que l’ensemble commence avec le bon alignement.
#include <stdalign.h>
alignas(16) static unsigned char pool[4096];
/* pool now begins on a 16-byte boundary */Une allocation alignée exécutable
Ce programme alloue de la mémoire dans une zone mémoire alignée et affiche l’adresse renvoyée modulo 16, montrant qu’elle vaut toujours zéro, c’est-à-dire qu’elle est correctement alignée.
#include <stdio.h>
#include <stddef.h>
#include <stdalign.h>
static size_t align_up(size_t n, size_t a){ return (n+a-1)&~(a-1); }
alignas(16) static unsigned char pool[1024];
static size_t off = 0;
void *alloc16(size_t s){ off=align_up(off,16); if(off+s>sizeof(pool)) return NULL; void*p=&pool[off]; off+=s; return p; }
int main(void){
void *a = alloc16(1);
void *b = alloc16(20);
printf("a %% 16 = %lu\n", (unsigned long)((size_t)a % 16));
printf("b %% 16 = %lu\n", (unsigned long)((size_t)b % 16));
return 0;
}Découpage et fusion
Le découpage et la fusion sont opposés et s’équilibrent mutuellement. L’allocation découpe les grands blocs ; la libération fusionne les petits blocs pour les reconstituer.
Ensemble, ils permettent à la même zone mémoire de servir un ensemble variable de tailles de demandes sans perdre d’espace ni se fragmenter définitivement.
Du modèle simplifié à l’allocateur réel
Vous disposez maintenant des quatre piliers : une source de mémoire, des en-têtes alignés, la réutilisation par liste de blocs libres avec fusion, et le découpage. Les allocateurs réels ajoutent des compartiments par classe de taille, des caches de threads et une intégration à l’OS pour gagner en rapidité et en capacité.
Mais les idées fondamentales que vous avez mises en œuvre ici alimentent chaque implémentation de malloc.
Vérification rapide
Réfléchissez à la raison pour laquelle les blocs sont découpés lors de l’allocation.
Récapitulatif
L’alignement arrondit les tailles vers le haut avec l’astuce sur les bits (n + a - 1) & ~(a - 1), afin que toute charge utile convienne à n’importe quel type. Le découpage transforme les blocs libres surdimensionnés en une partie utilisée et un reste libre, tandis que la fusion inverse cette opération lors de la libération.
Ces quatre piliers forment ensemble un allocateur de mémoire complet et correct.
Apprends C avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 39
- Leçons
- 144
Questions Fréquemment Posées
La leçon « Alignement et découpage » est-elle gratuite ?
Oui — le texte complet de « Alignement et découpage » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C Academy, passe à CoddyKit PRO. Le cours C Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Alignement et découpage » ?
Rendez les blocs utilisables et ordonnés. Tu pratiques C Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C Academy ?
Aucune expérience préalable n'est requise. C Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Alignement et découpage » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C Academy ?
Oui. Chaque leçon C Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Comment fonctionne malloc
- Un allocateur linéaire simple
- Listes libres et réutilisation
- Alignement et découpage