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 :

Liberation de memoire


Sujet :

C

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    527
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 527
    Points : 215
    Points
    215
    Par défaut Liberation de memoire
    Bonjour,
    Dans un petit developpement Windows, j'ai un soucis sur le "Free" d'un bloc de memoire alloué avec "malloc"
    J'ai le droit a une belle boite de dialogue me signalant une erreur :
    Module "dbgheap.c"
    Line ...
    Expression : _CrtIsValidHeapPointer(pUserData)
    Est ce parceque j'utilise des "memcpy" ou des "memmove" entre l'alloc et le free ?

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut Re: Liberation de memoire
    Citation Envoyé par dede92
    Bonjour,
    Dans un petit developpement Windows, j'ai un soucis sur le "Free" d'un bloc de memoire alloué avec "malloc"
    J'ai le droit a une belle boite de dialogue me signalant une erreur :
    Module "dbgheap.c"
    Line ...
    Expression : _CrtIsValidHeapPointer(pUserData)
    Est ce parceque j'utilise des "memcpy" ou des "memmove" entre l'alloc et le free ?
    Non, en principe , cela n'intervient pas... Comme toujours, post un code minimal compilable qui pose problème ou au moins les portions du code qui sont concernés...

    Jc

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    527
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 527
    Points : 215
    Points
    215
    Par défaut Re: Liberation de memoire
    Citation Envoyé par fearyourself
    Citation Envoyé par dede92
    Bonjour,
    Dans un petit developpement Windows, j'ai un soucis sur le "Free" d'un bloc de memoire alloué avec "malloc"
    J'ai le droit a une belle boite de dialogue me signalant une erreur :
    Module "dbgheap.c"
    Line ...
    Expression : _CrtIsValidHeapPointer(pUserData)
    Est ce parceque j'utilise des "memcpy" ou des "memmove" entre l'alloc et le free ?
    Non, en principe , cela n'intervient pas... Comme toujours, post un code minimal compilable qui pose problème ou au moins les portions du code qui sont concernés...

    Jc
    la fonction complète concernée :
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    static void TriCheckList(HWND hwnd, CHKLIST *lpList, char *lParam)
    {
     
    char *lpIn, *lpIn2;
    char *lpStr;
    static int sizeMem;
    static int depl, deplIn;
    static int offset, offset2;
    static int i, j;
    static int ll_num;
    static char ll[4];
    static char tag_info[2];
    char szBuffer[100];
    char tmp[10];
    char tmp2[10];
    char *data;
    BOOL stop;
     
        data = lParam;
     
        sizeMem = (int)lpList->nMember+1*(lpList->szMax + sizeof(ll) + sizeof(tag_info)); 
        lpIn=(char *)malloc(sizeMem) ;
    	lpIn2=lpIn;
     
    //Copie dans lpIn
    	     depl=0;
             lpStr = lpList->lpStr;
             for (j=0; j<lpList->nMember; j++) {
               lpStr+=depl;               //Long de la zone
               lpIn+=depl;
               ll_num = atoi(lpStr);
               memcpy(lpIn, lpStr, strlen(lpStr)+1);
               depl=sizeof(ll);
               lpStr+=depl;               //Tag Info
               lpIn+=depl;
               memcpy(lpIn, lpStr, strlen(lpStr)+1);
               depl=sizeof(tag_info);
               lpStr+=depl;               //Zone
               lpIn+=depl;
               memcpy(lpIn, lpStr, strlen(lpStr)+1);
               depl=ll_num+1;
    		 }
     
        stop=FALSE;
    	depl=0;
    	offset = 0;
    	offset2 = 0;
        lpStr = lpList->lpStr;
        for (i=0; i<lpList->nMember; i++) {
          lpStr+=depl;                     //Long de la zone
          ll_num = atoi(lpStr);
          lpStr+=sizeof(ll);               //Tag Info
    	  offset2+=sizeof(ll);
          lpStr+=sizeof(tag_info);         //Zone
    	  offset2+=sizeof(tag_info);
          if (strcmp(data, lpStr) < 0) { 
            stop=TRUE;
            deplIn=i;
            break;
    	  }
          lpStr+=(ll_num+1);
    	  offset2+=(ll_num+1);
    	}
        if (stop) { 
    //Recalage dans lpStr et dans lpIn
    	  lpStr-=sizeof(tag_info);
    	  offset2-=sizeof(tag_info);
          lpStr-=sizeof(ll);
    	  offset2-=sizeof(ll);
    //Insertion du nouvel Enregistrement
          itoa(strlen(data),ll,10);
    	  memcpy(lpStr, ll, strlen(ll)+1);
          lpStr+= sizeof(ll);
    	  strcpy(tag_info, "0");
          memcpy(lpStr, tag_info, strlen(tag_info)+1);
    	  lpStr+= sizeof(tag_info);
          memcpy(lpStr, data, strlen(data)+1);
          lpStr+=(strlen(data)+1);
          lpList->offset += (sizeof(ll) + sizeof(tag_info) + strlen(data)+1);
     
    //Copie du reste a partir de lpIn dans lpStr --------------------------------------
     
          lpIn=lpIn2;
     
          for (; i<lpList->nMember; i++) {
            ll_num = atoi(lpIn+offset2);                                 
    		memmove(lpStr, lpIn+offset2, strlen(ll)+1);
            offset2+= sizeof(ll);
            lpStr+=sizeof(ll);
    		memmove(lpStr, lpIn+offset2, strlen(tag_info)+1);
    	    offset2+= sizeof(tag_info);
            lpStr+= sizeof(tag_info);
            memmove(lpStr, lpIn+offset2, strlen(lpIn+offset2)+1);
            offset2+=(ll_num+1);
            lpStr+=(ll_num+1);
          }
          lpList->nMember++;
    	}
    	else {
    //Insertion du nouvel Enregistrement
          itoa(strlen(data),ll,10);
    	  memcpy(lpStr, ll, strlen(ll)+1);
          lpStr+= sizeof(ll);
    	  strcpy(tag_info, "0");
          memcpy(lpStr, tag_info, strlen(tag_info)+1);
    	  lpStr+= sizeof(tag_info);
          memcpy(lpStr, data, strlen(data)+1);
          lpStr+=(strlen(data)+1);
          lpList->offset += (sizeof(ll) + sizeof(tag_info) + strlen(data)+1);
          lpList->nMember++;
    	}
     
        if (lpIn=realloc(lpIn, sizeMem) != NULL) {
          size = _msize(lpIn);
          MessageBox (NULL, itoa(size,tmp,10), "Taille memoire", MB_OK | MB_ICONQUESTION);
    	  free(lpIn);
    	}
     
    }

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Salut
    Tu fais un lpIn=realloc(lpIn, sizeMem) ; et un free(lpIn); mais si je ne me trompes pas tu as modifé dans ton code lpIn : lpIn+=depl;
    donc ne t'étonnes pas si ça plante.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Beaucoup de choses ne vont pas dans cette fonction:

    On ne fait plus de transtypage après un malloc, par contre on teste le retour pour savoir s'il y a eu une erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    lpIn=malloc(sizeMem) ;  
    if(lpIn==NULL)
      {
      /* Gestion de l'erreur*/
      }
    On n'utilise plus atoi mais strtol:

    Ensuite, es-tu sûr de la taille allouée? Parce que si c'est vraiment la taille du champs à copier, pourquoi ne pas simplement faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    memcpy(lpIn, lpStr, sizeMem);
    Et finalement, si tu vas dans le else et non le if, tu ne remets pas lpIn à sa position initiale (stocké dans lpIn2) donc si tu fais un [EDIT]realloc/free[/EDIT] derrière, c'est sûr que cela ne plaira pas à l'ordinateur.

    Enfin, ton code est illisible, je comprends bien qu'il y a des recopies à faire et ainsi de suite, mais il y a sûrement des façon plus propre de le faire. Attends 2 semaines, regarde de nouveau ce code et tu me diras si tu y comprends encore quelque chose...

    Je ne vois pas non plus l'utilité de faire des memmove à la fin, des memcpy suffiraient, non?

    Jc

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    527
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 527
    Points : 215
    Points
    215
    Par défaut
    Oui c'est juste, il a surement une manière plus élégante de reecrire tout cela ...
    Je prends bonne note de vos remarques constructives !
    Pour le pointeur sur le malloc, comme effectivement, je le modifie avec des déplacements, donc impossible de faire un "Free" ?

  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 Re: Liberation de memoire
    Citation Envoyé par dede92
    Dans un petit developpement Windows, j'ai un soucis sur le "Free" d'un bloc de memoire alloué avec "malloc"
    free(), pas Free...
    J'ai le droit a une belle boite de dialogue me signalant une erreur :
    Module "dbgheap.c"
    Line ...
    Expression : _CrtIsValidHeapPointer(pUserData)
    Est ce parceque j'utilise des "memcpy" ou des "memmove" entre l'alloc et le free ?
    Possible si tu as eu des débordements (pas alloué assez de mémoire, par exemple... )
    Pas de Wi-Fi à la maison : CPL

  8. #8
    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 dede92
    Pour le pointeur sur le malloc, comme effectivement, je le modifie avec des déplacements, donc impossible de faire un "Free" ?
    L'adresse passée à free() doit être strictement celle donnée par malloc(), sinon, le comportement est indéfini.
    Pas de Wi-Fi à la maison : CPL

  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 Re: Liberation de memoire
    Citation Envoyé par dede92
    la fonction complète concernée :
    On pourrait l'avoir 'en C'
    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
     
    Compiling: main.c
    main.c:6: error: syntax error before "hwnd"
    main.c:7: warning: function declaration isn't a prototype
    main.c: In function `TriCheckList':
    main.c:22: error: `BOOL' undeclared (first use in this function)
    main.c:22: error: (Each undeclared identifier is reported only once
    main.c:22: error: for each function it appears in.)
    main.c:22: error: syntax error before "stop"
    main.c:24: error: `lParam' undeclared (first use in this function)
    main.c:26: error: `lpList' undeclared (first use in this function)
    main.c:27: error: implicit declaration of function `malloc'
    main.c:27: warning: nested extern declaration of `malloc'
    <internal>:0: warning: redundant redeclaration of 'malloc'
    main.c:27: warning: passing arg 1 of `malloc' as unsigned due to prototype
    main.c:36: error: implicit declaration of function `atoi'
    main.c:36: warning: nested extern declaration of `atoi'
    main.c:37: error: implicit declaration of function `memcpy'
    main.c:37: warning: nested extern declaration of `memcpy'
    <internal>:0: warning: redundant redeclaration of 'memcpy'
    main.c:37: error: implicit declaration of function `strlen'
    main.c:37: warning: nested extern declaration of `strlen'
    <internal>:0: warning: redundant redeclaration of 'strlen'
    main.c:49: error: `stop' undeclared (first use in this function)
    main.c:49: error: `FALSE' undeclared (first use in this function)
    main.c:56: warning: nested extern declaration of `atoi'
    main.c:36: warning: redundant redeclaration of 'atoi'
    main.c:36: warning: previous implicit declaration of 'atoi' was here
    main.c:61: error: implicit declaration of function `strcmp'
    main.c:61: warning: nested extern declaration of `strcmp'
    <internal>:0: warning: redundant redeclaration of 'strcmp'
    main.c:62: error: `TRUE' undeclared (first use in this function)
    main.c:76: error: implicit declaration of function `itoa'
    main.c:76: warning: nested extern declaration of `itoa'
    main.c:76: warning: nested extern declaration of `strlen'
    <internal>:0: warning: redundant redeclaration of 'strlen'
    main.c:77: warning: nested extern declaration of `memcpy'
    <internal>:0: warning: redundant redeclaration of 'memcpy'
    main.c:79: error: implicit declaration of function `strcpy'
    main.c:79: warning: nested extern declaration of `strcpy'
    <internal>:0: warning: redundant redeclaration of 'strcpy'
    main.c:91: warning: nested extern declaration of `atoi'
    main.c:36: warning: redundant redeclaration of 'atoi'
    main.c:36: warning: previous implicit declaration of 'atoi' was here
    main.c:92: error: implicit declaration of function `memmove'
    main.c:92: warning: nested extern declaration of `memmove'
    <internal>:0: warning: redundant redeclaration of 'memmove'
    main.c:106: warning: nested extern declaration of `itoa'
    main.c:76: warning: redundant redeclaration of 'itoa'
    main.c:76: warning: previous implicit declaration of 'itoa' was here
    main.c:106: warning: nested extern declaration of `strlen'
    <internal>:0: warning: redundant redeclaration of 'strlen'
    main.c:107: warning: nested extern declaration of `memcpy'
    <internal>:0: warning: redundant redeclaration of 'memcpy'
    main.c:109: warning: nested extern declaration of `strcpy'
    <internal>:0: warning: redundant redeclaration of 'strcpy'
    main.c:118: error: implicit declaration of function `realloc'
    main.c:118: warning: nested extern declaration of `realloc'
    main.c:118: error: `NULL' undeclared (first use in this function)
    main.c:119: error: `size' undeclared (first use in this function)
    main.c:119: error: implicit declaration of function `_msize'
    main.c:119: warning: nested extern declaration of `_msize'
    main.c:120: error: implicit declaration of function `MessageBox'
    main.c:120: warning: nested extern declaration of `MessageBox'
    main.c:120: warning: nested extern declaration of `itoa'
    main.c:76: warning: redundant redeclaration of 'itoa'
    main.c:76: warning: previous implicit declaration of 'itoa' was here
    main.c:120: error: `MB_OK' undeclared (first use in this function)
    main.c:120: error: `MB_ICONQUESTION' undeclared (first use in this function)
    main.c:121: error: implicit declaration of function `free'
    main.c:121: warning: nested extern declaration of `free'
    main.c:18: warning: unused variable `szBuffer'
    main.c:20: warning: unused variable `tmp2'
    main.c:124:2: warning: no newline at end of file
    main.c: At top level:
    main.c:7: warning: 'TriCheckList' defined but not used
    Process terminated with status 1 (0 minutes, 5 seconds)
    Pas de Wi-Fi à la maison : CPL

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je traduis en clair: Il manque les headers.
    au vu des messages d'erreurs, je dirais qu'il faut au moins <windows.h> et <string.h> (et sans doute d'autres)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    527
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 527
    Points : 215
    Points
    215
    Par défaut
    Citation Envoyé par Médinoc
    Je traduis en clair: Il manque les headers.
    au vu des messages d'erreurs, je dirais qu'il faut au moins <windows.h> et <string.h> (et sans doute d'autres)
    Certes, il en manque ...
    Quant au fonctionnement de "malloc()", en retour on a l'adresse du début du bloc alloué et je ne comprends pas pourquoi, si on fait un déplacement de +10 octets puis un déplacement de -10 octets, ce qui nous ramène a l'adresse de départ, la fonction "free()" est perdue ...

  12. #12
    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 dede92
    Quant au fonctionnement de "malloc()", en retour on a l'adresse du début du bloc alloué et je ne comprends pas pourquoi, si on fait un déplacement de +10 octets puis un déplacement de -10 octets, ce qui nous ramène a l'adresse de départ, la fonction "free()" est perdue ...
    C'est assez douteux comme manip. En principe, on a un pointeur 'fixe'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       T * pa = malloc(...);
     
       if (pa != NULL)
       {
          /* ... */
          free (pa), pa = NULL;
       }
    et dans /* ... */
    on peut jouer comme on veut avec un pointeur 'annexe', mais pa reste inchangé.
    Pas de Wi-Fi à la maison : CPL

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    527
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 527
    Points : 215
    Points
    215
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par dede92
    Quant au fonctionnement de "malloc()", en retour on a l'adresse du début du bloc alloué et je ne comprends pas pourquoi, si on fait un déplacement de +10 octets puis un déplacement de -10 octets, ce qui nous ramène a l'adresse de départ, la fonction "free()" est perdue ...
    C'est assez douteux comme manip. En principe, on a un pointeur 'fixe'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       T * pa = malloc(...);
     
       if (pa != NULL)
       {
          /* ... */
          free (pa), pa = NULL;
       }
    et dans /* ... */
    on peut jouer comme on veut avec un pointeur 'annexe', mais pa reste inchangé.
    c'est ce que j'ai essayé de faire sans succès
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    lpIn=(char *)malloc(sizeMem) ; 
       lpIn2=lpIn;
     .......
    .......
    lpIn = lpIn2;
    free(lpIn);

  14. #14
    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 dede92
    c'est ce que j'ai essayé de faire sans succès
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    lpIn=(char *)malloc(sizeMem) ; 
       lpIn2=lpIn;
     .......
    .......
    lpIn = lpIn2;
    free(lpIn);
    Ben non, justement, l'erreur est ici :
    Pourquoi tu fais çà ? Tu modifies la valeur originale qui est bonne avec une valeur douteuse. Je ne comprends pas le raisonnement ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       lpIn=(char *)malloc(sizeMem) ; 
       lpIn2=lpIn;
       .......
       .......
       free(lpIn);
    Voilà, tout simplement... Ce que je recommande de coder ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
       char *lpIn = malloc (sizeMem); 
       if (lpIn != NULL)
       {
          char * lpIn2 = lpIn;
          .......
          .......
          free(lpIn), lpIn = NULL;
       }
    Pas de Wi-Fi à la maison : CPL

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    527
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 527
    Points : 215
    Points
    215
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ben non, justement, l'erreur est ici :
    Pourquoi tu fais çà ? Tu modifies la valeur originale qui est bonne avec une valeur douteuse. Je ne comprends pas le raisonnement ...
    Pourquoi une valeur douteuse ?
    J'ai fait mes declarations :
    Je fais l'allocation suivie de la sauvegarde du pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn=(char *)malloc(sizeMem) ;
    	lpIn2=lpIn;
    et au moment de liberer, je restitue l'adresse originale du pointeur sauvegardé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn = lpIn2;
    free(lpIn);
    et c'est pas correct ?

  16. #16
    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 dede92
    J'ai fait mes declarations :
    Je fais l'allocation suivie de la sauvegarde du pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn=(char *)malloc(sizeMem) ;
    	lpIn2=lpIn;
    et au moment de liberer, je restitue l'adresse originale du pointeur sauvegardé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn = lpIn2;
    free(lpIn);
    et c'est pas correct ?
    Ok, je commence à comprendre (c'est moins facile quand on a pas tout le code...). Tu as créé un pointeur supplémentaire pour mémoriser la valeur initiale, et tu te sers du pointeur initial pour faire des manips, c'est ça ?
    Si je simplifie tu fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       T a = f();
       T b = a;
       a++;
       a++;
       a = b;
       g(a);
    alors qu'il est plus simple de faire comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       T a = f();
       {
          T b = a;
          b++;
          b++;
       }
       g(a);
    La portée de b peut êre limitée, et on ne risque pas de se tromper en a et b en appelant g().
    On peut même écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       T const a = f();
       {
          T b = a;
          b++;
          b++;
       }
       g(a);
    pour bien marquer notre intention de ne pas modifier a...
    Pas de Wi-Fi à la maison : CPL

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    527
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 527
    Points : 215
    Points
    215
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par dede92
    J'ai fait mes declarations :
    Je fais l'allocation suivie de la sauvegarde du pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn=(char *)malloc(sizeMem) ;
    	lpIn2=lpIn;
    et au moment de liberer, je restitue l'adresse originale du pointeur sauvegardé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn = lpIn2;
    free(lpIn);
    et c'est pas correct ?
    Ok, je commence à comprendre (c'est moins facile quand on a pas tout le code...). Tu as créé un pointeur supplémentaire pour mémoriser la valeur initiale, et tu te sers du pointeur initial pour faire des manips, c'est ça ?
    Si je simplifie tu fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       T a = f();
       T b = a;
       a++;
       a++;
       a = b;
       g(a);
    alors qu'il est plus simple de faire comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       T a = f();
       {
          T b = a;
          b++;
          b++;
       }
       g(a);
    La portée de b peut êre limitée, et on ne risque pas de se tromper en a et b en appelant g().
    On peut même écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       T const a = f();
       {
          T b = a;
          b++;
          b++;
       }
       g(a);
    pour bien marquer notre intention de ne pas modifier a...
    Oui c'est exactement ça
    J'ai modifié mon code et chaque fois que je modifiais le pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn+=depl;
               memcpy(lpIn, lpStr, strlen(lpStr)+1);
    j'ai codé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(lpIn+depl, lpStr, strlen(lpStr)+1);
    mais rien y fait il plante toujours au free() ...
    Normalement, si le free() échoue, la mémoire est quand même libérée en fin de thread ?

  18. #18
    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 dede92
    J'ai modifié mon code et chaque fois que je modifiais le pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lpIn+=depl;
               memcpy(lpIn, lpStr, strlen(lpStr)+1);
    j'ai codé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(lpIn+depl, lpStr, strlen(lpStr)+1);
    mais rien y fait il plante toujours au free() ...
    Alors tu as peut être un débordement de mémoire quelque part dans un bloc alloué qui a cassé des données internes de malloc()...

    Ca se manifeste alors à retardement au moment du free()...
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. question sur liberation de memoire
    Par nivose110 dans le forum C
    Réponses: 15
    Dernier message: 12/04/2007, 22h32
  2. Liberer la memoire
    Par Renardo dans le forum Access
    Réponses: 13
    Dernier message: 15/05/2006, 11h33
  3. liberation de memoire necessaire ?
    Par firejocker dans le forum C
    Réponses: 14
    Dernier message: 09/05/2006, 17h14
  4. liberer la memoire
    Par jopab04 dans le forum Langage
    Réponses: 14
    Dernier message: 11/02/2006, 15h56
  5. liberation de memoire d une fenetre modale
    Par ienien dans le forum MFC
    Réponses: 6
    Dernier message: 04/01/2006, 13h53

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