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 :

Probleme de malloc détecté par valgrind


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Probleme de malloc détecté par valgrind
    Bonjour.

    Valgrind m'indique un invalid free dans mon code (fichier harmony.c) , et je ne comprends pas pourquoi.

    Pour comprendre, voici le type Note_t utilisé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct _note{
     Pitch_t pitch;
     int midipitch;
     double start;
     double length;
     double weight;
    };
    typedef struct _note *Note_t;

    Voici le rapport valgrind

    ==29053== Invalid free() / delete / delete[]
    ==29053== at 0x402123A: free (vg_replace_malloc.c:233)
    ==29053== by 0x8057D60: noteChord_analysis (harmony.c:468)
    ==29053== by 0x805639A: harmony (harmony.c:60)
    ==29053== by 0x8059D43: harmony_cmd (cmd.c:58)
    ==29053== by 0x805A281: com_harmony (tonality.c:395)
    ==29053== by 0x8059FB6: execute_line (tonality.c:188)
    ==29053== by 0x805A7A1: main (tonality.c:144)
    ==29053== Address 0x4ACC1C0 is 0 bytes inside a block of size 32 free'd
    ==29053== at 0x402123A: free (vg_replace_malloc.c:233)
    ==29053== by 0x8057D2C: noteChord_analysis (harmony.c:464)
    ==29053== by 0x805639A: harmony (harmony.c:60)
    ==29053== by 0x8059D43: harmony_cmd (cmd.c:58)
    ==29053== by 0x805A281: com_harmony (tonality.c:395)
    ==29053== by 0x8059FB6: execute_line (tonality.c:188)
    ==29053== by 0x805A7A1: main (tonality.c:144)
    Et voici mon code issu de harmony.c (en gras les lignes 468 et 464, qui sont visées par valgrind):

    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
    35
    36
    int noteChord_analysis(NoteChord_t *noteChords, Score_t score, int nb_tracks, MidiFile_t midifile){
         int noteChords_size=0;
         int time=0;
         int next_time;
         int final_time=get_final_time(score, nb_tracks);
         int n_index=0;
         int j;
         int min_l=0; // min length for a noteChord, due to homorhythmic transformation
         Note_t *noteA=(Note_t*)malloc(500*sizeof(Note_t));
          for(j=0;j<500;j++){
                noteA[j]=(Note_t )malloc(sizeof(struct _note));
        }
         Note_t *noteB=(Note_t*)malloc(100*sizeof(Note_t));
          for(j=0;j<100;j++){
                noteB[j]=(Note_t )malloc(sizeof(struct _note));
        }
          while (time <= final_time){
                noteChords[n_index]->nb_notes=get_instant_notes(noteA, time, nb_tracks, score);
                min_l=get_min_length_among_notes(noteA, noteChords[n_index]->nb_notes);
                next_time=get_next_implicit_time(noteB,time, min_l, nb_tracks, score);
               fill_noteChord_pitches(noteA, noteChords[n_index]->nb_notes, noteChords, n_index, time, next_time-time);
               fill_noteChord_bass_and_root(noteChords, n_index);
               time=next_time;
               n_index ++;
               noteChords_size++;
        }
         for(j=0;j<500;j++){
              free(noteA[j]);
        }
         free(noteA);
         for(j=0;j<100;j++){
              free(noteB[j]);
        }
         free(noteB);
     return noteChords_size;
    }
    Voilà, je comprends rien. Visiblement, le second free libère un truc déjà libéré par le premier, mais je vois vraiment pas pourquoi.
    Il n'y a pas de dépassement, et valgrind ne me sort que cette erreur, à part lorsque le programme se termine, où il me sort celle là en plus:
    ==29053== Invalid free() / delete / delete[]
    ==29053== at 0x402123A: free (vg_replace_malloc.c:233)
    ==29053== by 0x804D309: destroy_score (score.c:45)
    ==29053== by 0x80564B7: harmony (harmony.c:96)
    ==29053== by 0x8059D43: harmony_cmd (cmd.c:58)
    ==29053== by 0x805A281: com_harmony (tonality.c:395)
    ==29053== by 0x8059FB6: execute_line (tonality.c:188)
    ==29053== by 0x805A7A1: main (tonality.c:144)
    ==29053== Address 0x4ACC1C0 is not stack'd, malloc'd or (recently) free'd
    Mais cette erreur là, je pense que c'est une conséquence de la première, parceque le fichier score.c ne comporte pas d'erreur de mémoire, il a été testé et retesté quand on l'a conçu il y a plusieurs moi, et valgrind bronche pas lorsque je le fais tourner seul.

    Je peux bien sur communiquer tout le fichier harmony.c (et d'autres fichiers) à qui l'estimerait necessaire pour trouver le problème.

    Ah oui, je peux préciser, avant, mon programme marchait nickel, sauf que noteA et noteB était déclarés comme suit:
    Note_t noteA[500];
    Note_t noteB[500];

    cela n'aurait jamais du marcher je suis d'accord, car seul un tableau de pointeur était déclaré, et aucun emplacement n'était réservé pour les structures, mais bon... ça marchait, ce qui est assez bizarre... et maintenant que je veux réparer cette erreur, et ben ça marche plus... du tout....

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 16
    Points : 19
    Points
    19
    Par défaut
    un truc pas clair :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Note_t *noteA=(Note_t*)malloc(500*sizeof(Note_t));
          for(j=0;j<500;j++){
                noteA[j]=(Note_t )malloc(sizeof(struct _note));
        }
         Note_t *noteB=(Note_t*)malloc(100*sizeof(Note_t));
          for(j=0;j<100;j++){
                noteB[j]=(Note_t )malloc(sizeof(struct _note));
        }
    peut etre que ceci irait mieux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Note_t **noteA=(Note_t**)malloc(500*sizeof(Note_t *));
          for(j=0;j<500;j++){
                noteA[j]=(Note_t *)malloc(sizeof(struct _note));
        }
    Note_t **noteB=(Note_t**)malloc(100*sizeof(Note_t*));
          for(j=0;j<100;j++){
                noteB[j]=(Note_t *)malloc(sizeof(struct _note));
        }
    Meme si je doute qu'il faille utiliser un vecteur de pointeurs sur des Note_t
    J'ai pas lu entierement le code mais si tu connais la taille de ton vecteur pourquoi ne pas utiliser un tableau tout simplement ?
    à mon avis il serait mieux de remplacer tout ça par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define TAILLE_MAX 500
    Note_t  noteA[TAILLE_MAX];
    Note_t noteB[TAILLE_MAX];
    et si tu dois initialiser ton tableau, memset est ton ami (cf string.h)

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par photonman Voir le message
    Valgrind m'indique un invalid free dans mon code (fichier harmony.c) , et je ne comprends pas pourquoi.

    Pour comprendre, voici le type Note_t utilisé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct _note{
     Pitch_t pitch;
     int midipitch;
     double start;
     double length;
     double weight;
    };
    typedef struct _note *Note_t;

    Voici le rapport valgrind



    Et voici mon code issu de harmony.c (en gras les lignes 468 et 464, qui sont visées par valgrind):
    Ce code n'est pas compilable, on ne peut rien tester.

    Ce qui est certain, par contre, cest que :
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    #include <stdlib.h>
     
    typedef struct
    {
       int dummy;
    }
    Pitch_t;
     
    struct _note
    {
       Pitch_t pitch;
       int midipitch;
       double start;
       double length;
       double weight;
    };
    typedef struct _note *Note_t;
     
    void noteChord_analysis (void)
    {
       int j;
       Note_t *noteA = malloc (500 * sizeof (Note_t));
       for (j = 0; j < 500; j++)
       {
          noteA[j] = (Note_t) malloc (sizeof (struct _note));
       }
       Note_t *noteB = (Note_t *) malloc (100 * sizeof (Note_t));
       for (j = 0; j < 100; j++)
       {
          noteB[j] = (Note_t) malloc (sizeof (struct _note));
       }
     
       for (j = 0; j < 500; j++)
       {
          free (noteA[j]);
       }
       free (noteA);
       for (j = 0; j < 100; j++)
       {
          free (noteB[j]);
       }
       free (noteB);
    }
     
    int main (void)
    {
       noteChord_analysis ();
     
       return 0;
    }
    bien que codé à la hussarde, se comporte correctement et terme d'allocation/libération. Le défaut est ailleurs.

    Il faut commencer par vérifier les tailles allouées... Un bon moyen est d'utiliser une méthode de codage sure et éprouvée. Je recommande ceci :
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    #include <stdlib.h>
    #include <assert.h>
     
    typedef struct
    {
       int dummy;
    }
    Pitch_t;
     
    struct _note
    {
       Pitch_t pitch;
       int midipitch;
       double start;
       double length;
       double weight;
    };
    typedef struct _note *Note_t;
    #define NA 500
    #define NB 100
     
    void noteChord_analysis (void)
    {
       int j;
       Note_t *noteA = malloc (NA * sizeof *noteA);
       if (noteA != NULL)
       {
          int err = 0;
          for (j = 0; j < NA; j++)
          {
             noteA[j] = malloc (sizeof *noteA[j]);
             if (noteA[j] == NULL)
             {
                err = 1;
             }
          }
     
          if (!err)
          {
             Note_t *noteB = malloc (NB * sizeof (Note_t));
             err = 0;
             for (j = 0; j < NB; j++)
             {
                noteB[j] = malloc (sizeof *noteB[j]);
                if (noteB[j] == NULL)
                {
                   err = 1;
                }
             }
     
             if (!err)
             {
                /* safe use */
             }
     
             for (j = 0; j < NB; j++)
             {
                free (noteB[j]);
             }
             free (noteB), noteB = NULL;
             assert (noteB == NULL);
          }
          for (j = 0; j < NA; j++)
          {
             free (noteA[j]);
          }
          free (noteA), noteA = NULL;
       }
       assert (noteA == NULL);
    }
     
    int main (void)
    {
       noteChord_analysis ();
     
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 16
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Ce code n'est pas compilable, on ne peut rien tester.
    oulala j'avais pas lu le m"chant typedef

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bonjour Emmanuel et mathieubo, te merci pour vos réponses.

    Tout d'abord, excusez moi pour l'oubli de la définition du type Pitch_t: c'est un typedef enum (donc un int a priori).

    J'ai modifié mon code selon les conseils d'Emmanuel:

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    int noteChord_analysis(NoteChord_t *noteChords, Score_t score, int nb_tracks, MidiFile_t midifile)
    {
       	int noteChords_size=0;
    	int time=0;
    	int next_time;
    	int final_time=get_final_time(score, nb_tracks);
    	int n_index=0;
    	int j;
    	int min_l=0; 
    
    	Note_t *noteA = malloc (NA * sizeof *noteA);
    	if (noteA != NULL)
    	{
          int err = 0;
          for (j = 0; j < NA; j++)
          {
             noteA[j] = malloc (sizeof *noteA[j]);
             if (noteA[j] == NULL)
             {
                err = 1;
             }
          }
     
          if (!err)
          {
             Note_t *noteB = malloc (NB * sizeof (Note_t));
             err = 0;
             for (j = 0; j < NB; j++)
             {
                noteB[j] = malloc (sizeof *noteB[j]);
                if (noteB[j] == NULL)
                {
                   err = 1;
                }
             }
     
             if (!err)
             {
                /* safe use */
    			printf("test\n");
    			while (time <= final_time){
    				noteChords[n_index]->nb_notes=get_instant_notes(noteA, time, nb_tracks, score);
    				min_l=get_min_length_among_notes(noteA, noteChords[n_index]->nb_notes);
    				next_time=get_next_implicit_time(noteB,time, min_l, nb_tracks, score);
    				fill_noteChord_pitches(noteA, noteChords[n_index]->nb_notes, noteChords, n_index, time, next_time-time);
    				fill_noteChord_bass_and_root(noteChords, n_index);
    				time=next_time;
    				n_index ++;
    				noteChords_size++;
    			}
             }
     
             for (j = 0; j < NB; j++)
             {
               free (noteB[j]);
             }
             free (noteB), noteB = NULL;
             assert (noteB == NULL);
          }
          for (j = 0; j < NA; j++)
          {
             free (noteA[j]);
          }
          free (noteA), noteA = NULL;
       }
       assert (noteA == NULL);
       return noteChords_size;
    }

    Le "test" s'affiche bien donc on est rentré dans la partie /* safe use*/.

    Mais valgrind me met toujours la même chose:

    ==27741== Invalid free() / delete / delete[]
    ==27741== at 0x402123A: free (vg_replace_malloc.c:233)
    ==27741== by 0x8057E32: noteChord_analysis (harmony.c:499)
    ==27741== by 0x80563DA: harmony (harmony.c:61)
    ==27741== by 0x8059E47: harmony_cmd (cmd.c:58)
    ==27741== by 0x805A381: com_harmony (tonality.c:395)
    ==27741== by 0x805A0B6: execute_line (tonality.c:188)
    ==27741== by 0x805A8A1: main (tonality.c:144)
    ==27741== Address 0x4ACC1C0 is 0 bytes inside a block of size 32 free'd
    ==27741== at 0x402123A: free (vg_replace_malloc.c:233)
    ==27741== by 0x8057DD0: noteChord_analysis (harmony.c:492)
    ==27741== by 0x80563DA: harmony (harmony.c:61)
    ==27741== by 0x8059E47: harmony_cmd (cmd.c:58)
    ==27741== by 0x805A381: com_harmony (tonality.c:395)
    ==27741== by 0x805A0B6: execute_line (tonality.c:188)
    ==27741== by 0x805A8A1: main (tonality.c:144)
    Où les 2 lignes incriminées sont encore en gras (les mêmes qu'avant).

    Il n'y a donc pas d'erreur lors de l'allocation visblement ? Vous voyez autre chose ?

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    un bon moyen de tester est : dans ton while, commente ligne a ligne...

    Le moment où ça marche, c'est l'instruction que tu viens juste de commenter
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    un bon moyen de tester est : dans ton while, commente ligne a ligne...

    Le moment où ça marche, c'est l'instruction que tu viens juste de commenter
    Absolument. Cette technique (isolation) est redoutablement efficace et bien connue.

    Je recommande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    /* code testé */
    #if 0
    /* code à testé */
    #endif
    Tu commences par :
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    int noteChord_analysis(NoteChord_t *noteChords, Score_t score, int nb_tracks, MidiFile_t midifile)
    {
       	int noteChords_size=0;
    	int time=0;
    	int next_time;
    	int final_time=get_final_time(score, nb_tracks);
    	int n_index=0;
    	int j;
    	int min_l=0; 
     
    	Note_t *noteA = malloc (NA * sizeof *noteA);
    	if (noteA != NULL)
    	{
          int err = 0;
          for (j = 0; j < NA; j++)
          {
             noteA[j] = malloc (sizeof *noteA[j]);
             if (noteA[j] == NULL)
             {
                err = 1;
             }
          }
     
          if (!err)
          {
             Note_t *noteB = malloc (NB * sizeof (Note_t));
             err = 0;
             for (j = 0; j < NB; j++)
             {
                noteB[j] = malloc (sizeof *noteB[j]);
                if (noteB[j] == NULL)
                {
                   err = 1;
                }
             }
     
             if (!err)
             {
                /* safe use */
    			printf("test\n");
    			while (time <= final_time){
    #if 0
    noteChords[n_index]->nb_notes=get_instant_notes(noteA, time, nb_tracks, score);
    				min_l=get_min_length_among_notes(noteA, noteChords[n_index]->nb_notes);
    				next_time=get_next_implicit_time(noteB,time, min_l, nb_tracks, score);
    				fill_noteChord_pitches(noteA, noteChords[n_index]->nb_notes, noteChords, n_index, time, next_time-time);
    				fill_noteChord_bass_and_root(noteChords, n_index);
    #endif
    				time=next_time;
    				n_index ++;
    				noteChords_size++;
    			}
             }
     
             for (j = 0; j < NB; j++)
             {
               free (noteB[j]);
             }
             free (noteB), noteB = NULL;
             assert (noteB == NULL);
          }
          for (j = 0; j < NA; j++)
          {
             free (noteA[j]);
          }
          free (noteA), noteA = NULL;
       }
       assert (noteA == NULL);
       return noteChords_size;
    }
    du moins en théorie, car il faut pouvoir sortir de la boucle, or next_time ne va pas changer d'où une boucle infinie...

    Il n'est pas rare que la méthode de l'isolation mette en évidence un problème dans le déroulement du code ou dans sa sécurité. Je vois 2 valeurs s'incrémenter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    				n_index ++;
    				noteChords_size++;
    Or il n'y a rien qui vérifie les limites de ces valeurs (d'où la boucle infinie quand on isole
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    next_time=get_next_implicit_time(noteB,time, min_l, nb_tracks, score);
    ). Est-ce bien logique tout ça ?
    Pas de Wi-Fi à la maison : CPL

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bon, voilà, j'ai procédé à la technique de l'isolation, et donc dès le premier essai:
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    int noteChord_analysis(NoteChord_t *noteChords, Score_t score, int nb_tracks, MidiFile_t midifile)
    {
       	int noteChords_size=0;
    	int time=0;
    	int next_time;
    	int final_time=get_final_time(score, nb_tracks);
    	int n_index=0;
    	int j;
    	int min_l=0; // min length for a noteChord, due to homorhythmic transformation
     
    	Note_t *noteA = malloc (NA * sizeof *noteA);
    	if (noteA != NULL)
    	{
          int err = 0;
          for (j = 0; j < NA; j++)
          {
             noteA[j] = malloc (sizeof *noteA[j]);
             if (noteA[j] == NULL)
             {
                err = 1;
             }
          }
     
          if (!err)
          {
             Note_t *noteB = malloc (NB * sizeof (Note_t));
             err = 0;
             for (j = 0; j < NB; j++)
             {
                noteB[j] = malloc (sizeof *noteB[j]);
                if (noteB[j] == NULL)
                {
                   err = 1;
                }
             }
     
             if (!err)
             {
                /* safe use */
    			printf("test\n");
     
    			while (time <= final_time){
    				noteChords[n_index]->nb_notes=get_instant_notes(noteA, time, nb_tracks, score);
    				//min_l=get_min_length_among_notes(noteA, noteChords[n_index]->nb_notes);
    				//next_time=get_next_implicit_time(noteB,time, min_l, nb_tracks, score);
    				//fill_noteChord_pitches(noteA, noteChords[n_index]->nb_notes, noteChords, n_index, time, next_time-time);
    				//fill_noteChord_bass_and_root(noteChords, n_index);
    				//time=next_time;
    				//n_index ++;
    				//noteChords_size++;
    				time=final_time+1;
     
    			}
     
    		}
     
             for (j = 0; j < NB; j++)
             {
                free (noteB[j]);
             }
             free (noteB), noteB = NULL;
             assert (noteB == NULL);
          }
          for (j = 0; j < NA; j++)
          {
             free (noteA[j]);
          }
          free (noteA), noteA = NULL;
       }
       assert (noteA == NULL);
       return noteChords_size;
    }
    L'erreur de invalid free que je mentionnais auparavant a disparu, et donc on quite la fonction sans erreur de libération aux 2 lignes concernées. En revanche, la seconde erreur que je mentionnais tout au début, elle, persiste (et fait référence à une autre fonction, sur un autre fichier).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ==11918==    at 0x402123A: free (vg_replace_malloc.c:233)
    ==11918==    by 0x804D349: destroy_score (score.c:45)
    ==11918==    by 0x80564DE: harmony (harmony.c:97)
    ==11918==    by 0x8059D7B: harmony_cmd (cmd.c:58)
    ==11918==    by 0x805A2B1: com_harmony (tonality.c:395)
    ==11918==    by 0x8059FE6: execute_line (tonality.c:188)
    ==11918==    by 0x805A7D1: main (tonality.c:144)
    Donc je ne sais pas quelle est la stratégie à adopter:

    - Soit je me dis qu'il y'avait une ereur dans le bloc while commenté ci-dessus et je cherche de ce coté
    - Soit je me dis que l'erreur est dans le fichier score.c, ligne 45... mais encore une fois c'est étrange car valgrind ne fait pas d'erreur lorsque toute la fonction noteChord_analysis est commentée, et donc la libération se fait bien dans score.c


    A tout hasard, je mets le code de la fonction score.c, avec en gras la ligne 45 (qui est censée produire l'erreur).
    Tout d'abord les types:
    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 _track{
    Note_t * note;
    int length;
    };
    typedef struct _track *Track_t;
     
     
    struct _score{
    Track_t * tracks;
    int nb_tracks;
    Tonality_t assumed_tonality;
    };
    typedef struct _score *Score_t;
    et les fonctions d'allocation et de libération de score:
    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
    35
    36
    37
    Score_t create_score(int nb_tracks){
    
    	int i,j;
    	Score_t score;
    	
    	score=(Score_t)malloc(sizeof(struct _score));
     
    	score->tracks=(Track_t *)malloc(nb_tracks*sizeof(Track_t));
    	
    
      for(i=0;i<nb_tracks;i++){
    	score->tracks[i]=(Track_t)malloc(sizeof(struct _track));
    	score->tracks[i]->note=(Note_t *)malloc(MAX_NOTES*sizeof(Note_t));
    	for(j=0;j<MAX_NOTES;j++){
    	score->tracks[i]->note[j]=(Note_t )malloc(sizeof(struct _note));
    	}
    }
    
    	
    
    	return score;
    }
    
    
    void destroy_score(Score_t score){
    int i,j;
     for(i=0;i<score->nb_tracks;i++){
    		for(j=0;j<MAX_NOTES;j++){
    		free(score->tracks[i]->note[j]);
    		}
    	free(score->tracks[i]->note);
    	free(score->tracks[i]);
    	}
    free(score->tracks);
    free(score);
    }

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par photonman Voir le message
    Bon, voilà, j'ai procédé à la technique de l'isolation, et donc dès le premier essai:

    int noteChord_analysis(NoteChord_t *noteChords, Score_t score, int nb_tracks, MidiFile_t midifile)
    {
    C'est si difficile que ça de mettre les balises de code ?
    Pas de Wi-Fi à la maison : CPL

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Désolé pour l'oubli des balises.

    Bon, mon problème est résolu, voici les détails au cas ça arriverait à quelqu'un d'autre.
    J'ai alloué en début de programme un immense tableau de pointeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Note_t *tableau_1=(Note_t*)malloc(MAX_NOTES*sizeof(Note_t))
    où Note_t est donc un pointeur vers une structure

    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 _note{
     
    Pitch_t pitch;
     
    int midipitch;
     
    double start;
     
    double length;
     
    double weight;
     
    };
    typedef struct _note *Note_t;
    En cours de programme, je devais stocker certaines notes dans un tableau temporaire, ce que je faisais d'abord en créant un tableau semblable au précédent:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Note_t *tableau_temp=(Note_t*)malloc(500*sizeof(Note_t))
    puis, pour "copier" une note de l'un dans l'autre, l'erreur suivante:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tableau_temp[i]=tableau_1[k];
    Evidemment, seule l'adresse était copiée dans le tableau, et lorsque je libérais tableau_temp, je liberai en même temps une adresse dans tableau_1. Suite à quoi, la libération de tableau_1 en fin de programme me provoquait l'erreur de double free.

    J'ai donc simplement transformée mes affectation en:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(tableau_temp[i],tableau_1[k],sizeof*tableau_temp[i])
    En tout cas merci pour les conseils concernant l'isolation de code, ça m'aura beaucoup aidé.
    Merci à tous ceux qui ont répondu à mon post !!

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut


    t'aurais pu faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *tableau_temp[i]=*tableau_1[k];
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

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

Discussions similaires

  1. Erreur mémoire détectée par Valgrind mais non trouvable
    Par alpha_one_x86 dans le forum C++/CLI
    Réponses: 7
    Dernier message: 12/08/2014, 19h11
  2. Réponses: 21
    Dernier message: 01/09/2011, 09h56
  3. Problèmes détectés par Valgrind
    Par tino56 dans le forum OpenCV
    Réponses: 0
    Dernier message: 24/10/2008, 09h46
  4. Probleme sur le passage par reference
    Par schnito dans le forum Langage
    Réponses: 10
    Dernier message: 02/02/2006, 16h50
  5. probleme avec une division par zéro
    Par jcharleszoxi dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/03/2003, 18h14

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