La plupart des implémentations des fonctions d'allocation de mémoire en C stockeront les informations de comptabilité pour chaque bloc, soit en ligne, soit séparément.
Une méthode typique (en ligne) consiste à allouer à la fois un en-tête et la mémoire que vous avez demandée, en la complétant jusqu'à une taille minimale. Ainsi, par exemple, si vous avez demandé 20 octets, le système peut allouer un bloc de 48 octets :
- En-tête de 16 octets contenant la taille, le marqueur spécial, la somme de contrôle, les pointeurs vers le bloc suivant/précédent et ainsi de suite.
- Une zone de données de 32 octets (vos 20 octets arrondis à un multiple de 16).
L'adresse qui vous est alors donnée est l'adresse de la zone de données. Ensuite, lorsque vous libérez le bloc, free
prendra simplement l'adresse que vous lui donnez et, en supposant que vous n'avez pas détruit cette adresse ou la mémoire qui l'entoure, vérifiera les informations comptables qui la précèdent immédiatement. Graphiquement, cela ressemblerait à ceci :
____ The allocated block ____
/ \
+--------+--------------------+
| Header | Your data area ... |
+--------+--------------------+
^
|
+-- The address you are given
Gardez à l'esprit que la taille de l'en-tête et le remplissage sont totalement définis par l'implémentation (en fait, tout est défini par l'implémentation). (a) mais l'option de comptabilité en ligne est courante).
Les sommes de contrôle et les marqueurs spéciaux qui existent dans les informations comptables sont souvent à l'origine d'erreurs telles que "Memory arena corrupted" ou "Double free" si vous les écrasez ou les libérez deux fois.
Le remplissage (pour rendre l'allocation plus efficace) est la raison pour laquelle vous pouvez parfois écrire un peu au-delà de la fin de l'espace demandé sans causer de problèmes (mais ne le faites pas, c'est un comportement non défini et ce n'est pas parce que cela fonctionne parfois qu'il faut le faire).
(a) J'ai écrit des implémentations de malloc
dans les systèmes embarqués où l'on obtenait 128 octets quoi que l'on demande (c'était la taille de la plus grande structure du système), en supposant que l'on demandait 128 octets ou moins (les demandes pour plus seraient accueillies par une valeur de retour NULL). Un masque de bits très simple (c'est-à-dire, pas en ligne) était utilisé pour décider si un morceau de 128 octets était alloué ou non.
D'autres que j'ai développés avaient des pools différents pour les blocs de 16 octets, 64 octets, 256 octets et 1K, en utilisant à nouveau un masque de bits pour décider quels blocs étaient utilisés ou disponibles.
Ces deux options ont permis de réduire les frais généraux liés à l'information comptable et d'augmenter la vitesse de traitement des données. malloc
et free
(pas besoin de coalescer les blocs adjacents lors de la libération), particulièrement important dans l'environnement dans lequel nous travaillions.
0 votes
Une question similaire : stackoverflow.com/questions/851958/ (bien que je dirais que ce n'est pas tout à fait un double)
0 votes
Le site système de jumelage Il existe un autre moyen de le faire, qui peut le déterminer sur la base du pointeur, sans surcharge dans chaque bloc.
0 votes
Ce billet l'explique bien : stackoverflow.com/questions/1957099/