IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Fuites mémoires malloc


Sujet :

C

  1. #1
    Futur Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 8
    Points : 6
    Points
    6
    Par défaut Fuites mémoires malloc
    Bonjour,

    Lors de l'ajout d'un élément dans ma liste chaînée, au bout d'un certain temps, j'ai soit :

    malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
    soit

    malloc(): memory corruption
    La fonction en question est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    int
    add_list(struct list **list, char *string) {
        struct list *tmp;
        struct list *node;
        int length;
     
        if (string == NULL)
            return -1;
     
        length = strlen(string)+1;
     
        if ((node = allocate_list()) == NULL)
            return -1;
     
        puts("1");
        if ((node->string = malloc(sizeof(char)*(length))) == NULL) {
            fprintf(stderr, "malloc error in %s at line %d\n", __FILE__, __LINE__);
            return -1;
        }
        puts("2");
     
        strncpy(node->string, string, length);
        node->string[length-1] = '\0';
     
        if ((*list) == NULL) {
            *list = node;
            return 1;
        }
     
        for (tmp = *list; tmp->next != NULL; tmp = tmp->next);
        tmp->next = node;
     
        return 1;
    }
    Cela peut se passer après l'ajout de plusieurs éléments comme au premier ajout.

    Contexte d'utilisation de la fonction :

    je récupère sur stdin une chaine de caractère via les fonctions de la libreadline.
    Cette chaine de caractère correspond à une fonction dans un .so qui est chargée à sa première utilisation. Cette chaine est divisée en deux : le nom de la fonction et ses arguments. Les arguments sont stoqués dans un tableau de char* genre argv. Pour l'ajout d'un élément, je boucle donc dans ce tableau et ajoute dans une liste initialisée à NULL chacune de mes chaines.

    Voici la fonction dans laquelle à lieu la boucle des ajouts :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    struct stack
    list (char **args, struct stack *stack) {
        int i = 0;
        struct list *list = NULL;
     
        if (*args == NULL || args == NULL)
            return;
     
        for (i = 0; args[i] != NULL; i++)
            add_list(&list, args[i]);
     
        disp_list(list);
     
        if ((push(stack, list) == -1))
            puts("problem");
     
        return *stack;
    }
    Et voici les situations dans lesquels les erreurs se produisent :

    rudy@ubuntu:~/C$ ./bin/a.out
    $ list a b c
    *** glibc detected *** ./bin/a.out: malloc(): memory corruption: 0x08d86848 ***
    ======= Backtrace: =========
    ...
    rudy@ubuntu:~/C$ ./bin/a.out
    $ list a
    a
    $ list a b c
    a.out: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
    Abandon
    « list » ajoute dans une nouvelle liste chaînée l'ensemble de ses arguments (celles-ci sont empilées au fur et à mesure, mais ça, ça semble fonctionner).

    Par avance merci,

    Rudy.

  2. #2
    Membre éclairé
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Points : 747
    Points
    747
    Par défaut
    En fait, tu ne set jamais node->next à NULL ! Du coup, tout peut arriver.


    Rq: je te conseillerais de mette ton for(); comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (tmp = *list; tmp->next != NULL; tmp = tmp->next)
        /* nop */;
    Car quelqu'un qui relit peut (c'est ce que j'ai fait) y voir un bug. Autant expliciter.

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Il y a une fuite potentielle ici aussi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        if ((node = allocate_list()) == NULL)
            return -1;
     
        puts("1");
        if ((node->string = malloc(sizeof(char)*(length))) == NULL) {
            fprintf(stderr, "malloc error in %s at line %d\n", __FILE__, __LINE__);
            return -1;
        }
    Si la première allocation réussit mais que la seconde échoue, il y a fuite de mémoire. En supposant bien sûr que allocate_list (dont on n'a pas le code) ne fait qu'allouer de la mémoire grâce à un malloc/calloc/realloc et retourne l'adresse en question...

  4. #4
    Futur Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Merci pour vos réponses.

    En effet, j'ai oublié de copier la fonction allocate_list(); désolé. La voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct list *
    allocate_list() {
        struct list *node;
     
        if ((node = malloc(sizeof(*node))) == NULL) {
            fprintf(stderr, "malloc error in %s at line %d\n", __FILE__, __LINE__);
            return NULL;
        }
     
        node->string = NULL;
        node->next = NULL;
     
        return node;
    }
    node->next est donc déjà à NULL, c'est pourquoi je fais uniquement un tmp->next = node; lors de l'ajout.
    Je n'arrive vraiment pas à situer mon erreur.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Si c'est pas trop long, donne le code complet ou sinon un code simplifié et compilable reproduisant l'erreur.
    Car apparemment le problème vient d'ailleurs. J'ai fait juste un test comme ça, en bidouillant ton code (vu qu'il manque la définition des structures, ainsi que certaines fonctions), et j'ai rien vu de spécial. Mais comme c'est du bricolage, je suis peut-être passé à côté de quelque chose...

  6. #6
    Membre éclairé
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Points : 747
    Points
    747
    Par défaut
    Tout pareil que jeroman, à mon avis le pb vient d'ailleurs (disp_list(), push() ?). Il faut plus d'info.

  7. #7
    Futur Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Bonjour.

    Tout d'abord, merci pour votre aide.
    J'ai trouvé mon erreur, il me manquait un octet lors de l'allocation de ma variable args pour stocker les chaînes. Cela se passait sans encombre jusqu'à présent, je n'avais donc pas vu le problême. Veuillez m'excuser pour cette erreur d'inattention.

    En vous remerciant une fois de plus,
    cordialement,

    Rudy.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [tomcat][memoire] java.net.URL et fuite mémoire
    Par Seiya dans le forum Tomcat et TomEE
    Réponses: 6
    Dernier message: 09/03/2009, 11h41
  2. [Fuites mémoire] Je cherche un utilitaire
    Par 10_GOTO_10 dans le forum C++Builder
    Réponses: 8
    Dernier message: 10/02/2005, 11h03
  3. Outil de recherche de fuite mémoire
    Par eag35 dans le forum MFC
    Réponses: 4
    Dernier message: 02/02/2005, 13h46
  4. [SWT]SWT et fuite mémoire(ou pas)
    Par menuge dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 22/06/2004, 22h40
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 18h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo