faire coutume Malloc, qu’est-ce qui ne va pas ici?

Je travaille depuis un certain temps sur un petit client maléfique personnalisé, à l’aide d’une liste à double liaison, et bien que cela soit petit, j’ai pensé que cela fonctionnerait. Y at-il quelque chose d’évident qui ne va pas avec ce code?

#include  #include  #include  #include  #include "mymal.h" typedef struct Node { int size; int status; struct Node *next; struct Node *previous; } Node; Node *endNode; Node *rootNode; void *worstfit_mall(int size) { Node *theNode = sbrk (size + sizeof(theNode)); void *ptr; if (rootNode == NULL) { theNode->status = 1; theNode->size = size; theNode->previous = theNode; theNode->next = theNode; rootNode = theNode; endNode = theNode; return theNode; } Node *worstNode; worstNode = worstFit(size); if (worstNode != NULL) { theNode->status = 1; theNode->size = size; Node *newNode = sbrk((worstNode->size - theNode->size) + sizeof(theNode)); newNode->status = 0; newNode->size = worstNode->size - theNode->size; theNode->next = newNode; theNode->previous = worstNode->previous; newNode->next = worstNode->next; return newNode; } endNode->next = theNode; endNode = theNode; endNode->status = 1; endNode->size = size; ptr = sbrk(size + sizeof(theNode)); return ptr; } void my_free(void *ptr) { Node *pointer; pointer = (Node*)ptr; pointer->status = 0; if ((pointer->next->status == 0) && (pointer->previous->status == 0)) sbrk(-1 * (pointer->next->size + pointer->size)); else if ((pointer->next->status == 1) && (pointer->previous->status == 0)) sbrk(-1 * (pointer->previous->size + pointer->size)); else if ((pointer->next->status == 0) && ( pointer->next->status == 0)) sbrk(-1 * (pointer->previous->size + pointer->next->size + pointer->size)); else sbrk(-1 * pointer->size); } void *worstFit(int size) { Node *theNode = rootNode; Node *worstNode; while (theNode != NULL) { if ((worstNode == NULL || theNode->size > worstNode->size) && (theNode->size >= size) && (theNode->status == 0)) worstNode = theNode; theNode = theNode->next; } return worstNode; } 

Voici les choses qui me frappent immédiatement:

  • worstFit pas worstNode à NULL et essaie de le lire tant qu’il est bourré.

  • Vous créez une liste chaînée de Node , mais le Node queue next pointe toujours sur lui-même. Pendant ce temps, worstFit que worstFit attend une NULL sentinel quand il itère sur la liste.

  • worstfit_mall pas endNode lors de la création initiale de rootNode .

  • worstfit_mall renvoie un pointeur sur le Node alloué, mais s’il est censé être substituable à malloc , il devrait renvoyer un pointeur en mémoire sur lequel l’appelant est autorisé à écrire. Vous ne voulez pas que l’appelant gribouille vos données de Node .

    Je m’attendrais à ce que worstfit_mall renvoie ((char*) node) + sizeof *node) (ou plus simplement, node + 1 ) au lieu de retourner directement node . my_free devra effectuer un ajustement inverse correspondant pour récupérer le pointeur Node .

    void my_free(void *ptr) { Node *nodePtr = ptr; nodePtr--; ... }

  • De plus, je ne comprends pas worstfit_mall pourquoi worstfit_mall alloue de la mémoire via sbrk lors de la descente du worstNode != NULL chemin worstNode != NULL . Le sharepoint ce chemin n’est-il pas de trouver un bloc de mémoire existant à réutiliser? De plus, ce chemin appelle sbrk deux fois .

  • Enfin, il me semble que my_free réduit inconditionnellement la quantité de mémoire allouée, mais cela ne fonctionnerait que si vous libériez la dernière chose que vous avez allouée avec sbrk . Et si vous worstfit_mall deux fois worstfit_mall , puis my_free lors du premier résultat? Il n’y a pas de chemin où my_free marque le bloc de mémoire comme n’étant plus utilisé, de sorte que ce worstfit_mall puisse le réutiliser ultérieurement.

Je ne sais pas s’il y a d’autres problèmes avec votre code; Je dirais que ces types de problèmes fondamentaux sont très probablement abordés.