2017-10-17 17 views
1

que je recherchais dans certaines implémentations de gestion de la mémoire (pool + malloc + free) en utilisant la liste chaînée, et je trouve que dans la plupart d'entre eux chaque nœud est quelque chose comme ceci:Pourquoi le pointeur suivant est-il proche du sommet du noeud?

typedef struct node{ 
int usedSize; 
node* next; 
char mem[100]; 
} 

et le free(ptr) doit être:

free(void* ptr){ 
node* item = (node*)((char*)ptr - sizeof(node*) - sizeof(int)); 
\\some code to put the "item" back to the pool 
} 

Ma question est la suivante: pourquoi ne pas mettre le char mem[100]; au début de la structure pour éviter la « manipulation du pointeur »?

le résultat est:

typedef struct node{ 
char mem[100]; // moved to the beginning 
int usedSize; 
node* next; 
} 

puis le free(ptr) est plus simple:

free(void* ptr){ 
node* item = (node*)((char*)ptr); 
\\some code to put "item" back to the pool 
} 

Merci.

+1

Cela fonctionnerait correctement si toutes les allocations étaient exactement de 100 octets. Mais si les allocations diffèrent en taille, comment trouvez-vous la taille de l'allocation? Mettre la taille juste avant l'allocation la rend simple. – rici

+0

whonks @rici mais je n'ai pas besoin de le trouver, je peux y accéder en utilisant node-> usedSize Ai-je raté quelque chose? – mvk

+0

merci @jxh pour la réponse (3) dont je n'étais pas au courant. – mvk

Répondre

1
  1. Cette manipulation de pointeur n'est pas particulièrement compliquée. Cela revient à une décrémentation par une constante de temps de compilation. Comme il est indiqué dans les commentaires, il devrait en fait être:

    node* item = (node*)((char*)ptr - offsetof(struct node, mem)); 
    
  2. Placer cet en-tête au-dessus de la mémoire permet à la mémoire d'être représenté par un membre flexible. Un membre de groupe flexible ne peut occuper que la dernière position d'une structure. Cela a également été noté dans les commentaires.

    typedef struct node { 
        int usedSize; 
        node* next; 
        char mem[]; 
    } node; 
    
  3. Si la taille de la mémoire est grande, sautant par-dessus le tableau pour atteindre le pointeur suivant seront les lignes de cache de données susceptibles de chasse pour charger les données de comptabilité. Cependant, un court saut en arrière de la baie va probablement accéder aux données déjà chargées dans le cache.