3 votes

Malloc de base/libre

Si j'ai un extrait de mon programme comme ceci :

struct Node *node;
while(...){
    node = malloc(100);
    //do stuff with node
}

Cela signifie qu'à chaque fois que je passe par la boucle while, je dois allouer 100 octets qui sont pointés par le pointeur de nœud, n'est-ce pas ?

Si c'est vrai, alors comment puis-je libérer toute la mémoire que j'ai créée avec toutes les boucles si je n'ai plus qu'un pointeur pointant sur le dernier malloc qui s'est produit ?

Merci !

4voto

sarnold Points 62720

Veuillez allouer exactement la taille dont vous avez besoin : malloc(sizeof *node); -- si vous passez à une plate-forme 64 bits qui double la taille de tous vos membres, votre ancienne structure de 96 octets pourrait prendre 192 octets dans le nouvel environnement.

Si vous n'avez pas de pointeur sur l'un des éléments de la struct Node que vous avez créées, alors je ne pense pas que vous devriez les allouer avec des malloc(3) en premier lieu. malloc(3) est la meilleure solution si votre application exige que les données persistent en dehors de la portée d'appel de la fonction actuelle. I s'attendre à que vous pourriez réécrire votre fonction comme ceci :

struct Node node;
while(...){
    //do stuff with node
}

ou

while(...){
    struct Node node;
    //do stuff with node
}

selon que vous voulez accéder au dernier nœud (la première version) ou non (la deuxième version).

Bien sûr, si vous avez réellement besoin de ces structures en dehors de ce morceau de code, vous devez y stocker des références quelque part . Ajoutez-les à une liste globale en gardant la trace de struct Node ou ajouter chacun d'eux à la liste des objets next du pointeur de la précédent struct Node ou ajouter chacun d'entre eux à un struct User qui s'y réfère, ce qui est le mieux pour votre application.

1voto

Jim Rhodes Points 2280

Si vous définissez node = NULL avant la boucle et que vous utilisez free(node) avant node = malloc(100), tout devrait bien se passer. Vous aurez également besoin de faire un free(node) après la sortie de la boucle. Mais encore une fois, tout dépend de ce que "//do stuff with node" fait réellement. Comme d'autres l'ont souligné, malloc(100) n'est pas une bonne idée. Ce que j'utiliserais est malloc(sizeof(*node)). De cette façon, si le type de noeud change, vous n'avez pas à changer la ligne malloc.

1voto

Kay Points 8052

Si vous n'avez plus besoin de l'espace malloqué à la fin d'une itération, vous devez le libérer immédiatement.

Pour garder la trace des nœuds alloués, vous pouvez les enregistrer dans une liste qui croît dynamiquement :

#include <stdlib.h>

int main() {
    int i;
    void *node;
    int prt_len = 0;
    void **ptrs = NULL;
    for (i = 0; i < 10; i++) {
        node = malloc(100);
        ptrs = realloc(ptrs, sizeof(void*) * ++prt_len);
        ptrs[prt_len-1] = node;
        /* code */
    }
    for (i = 0; i < prt_len; i++) {
        free(ptrs[i]);
    }
    free(ptrs);
    return 0;
}

Note : Vous devriez probablement repenser votre algorithme si vous devez employer de telles méthodes !

Sinon, voir réponse de sarnold .

0voto

Brian Roach Points 43787

alors comment puis-je libérer toute la mémoire que j'ai créée avec toutes les boucles si je n'ai plus qu'un pointeur pointant sur le dernier malloc qui s'est produit ?

Tu ne peux pas. Tu viens de créer un géant fuite de mémoire .

Vous devez garder la trace de chaque morceau de mémoire que vous malloc() y free() quand vous avez fini de l'utiliser.

0voto

Vous ne pouvez pas. Vous devez enregistrer tous les pointeurs pour libérer la mémoire. Si vous enregistrez ces pointeurs quelque part, alors vous seul pouvez libérer la mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X