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 :

Problème de libération de mémoire


Sujet :

C

  1. #1
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2008
    Messages
    19
    Points
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2008
    Messages : 19
    Points : 76
    Par défaut Problème de libération de mémoire
    Bonjour,

    Je rencontre en ce moment un problème auquel je ne parviens pas à trouver de solution:

    J'ai un tableau (à une dimension) dont les éléments sont des pointeurs vers de la mémoire qui a été allouée. Seulement, plusieurs pointeurs de ce tableau, pointent vers la même zone mémoire.
    C'est là que le problème se pose, si je fais une boucle pour parcourir le tableau et libérer la mémoire qui a été allouée je fais par exemple un free(p) où p est le premier pointeur du tableau et puis quand je passe au deuxième pointeur du tableau, si celui-ci pointait vers la même zone mémoire que le premier alors je ne dois plus le libérer. Mais comment le savoir ? car ce deuxième pointeur qui ne pointe plus sur rien à cause du premier free(p) n'est pas NULL... J'espère que j'ai été clair...

    D'avance merci pour votre aide

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Points
    8 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Par défaut
    Ce n'est pas une variable qu'on libère mais la mémoire. Tu peux avoir 100 variables pointant vers la même mémoire (allouée dynamiquement), elles contiennent donc toutes la même adresse. Une seule d'entre elles suffit pour libérer la mémoire.

  3. #3
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Points
    5 360
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Par défaut
    Une manière de faire est d'éviter les doublons en copiant les adresses de ton tableau dans un 2ème tableau (on ne copie qu'une seule fois chaque adresse). Ensuite, on itère sur le 2ème tableau pour libérer la mémoire.

    Si on ne veut pas dupliquer le tableau, on peut commencer par le trier en place à l'aide de qsort() de manière à grouper les doublons. On met ensuite chaque doublon à NULL, puis on itère sur le tableau pour libérer la mémoire.

    Thierry

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Points
    5 360
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Par défaut
    Citation Envoyé par Melem Voir le message
    Ce n'est pas une variable qu'on libère mais la mémoire. Tu peux avoir 100 variables pointant vers la même mémoire (allouée dynamiquement), elles contiennent donc toutes la même adresse. Une seule d'entre elles suffit pour libérer la mémoire.
    Le problème, c'est que passer à free() une adresse invalide (ici, invalide signifie: 'dont la mémoire a déjà été libérée') différente de NULL engendre un comportement indéterminé.

    Thierry

  5. #5
    Membre régulier
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2008
    Messages
    19
    Points
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2008
    Messages : 19
    Points : 76
    Par défaut
    Ok merci Thierry je vais faire ça
    Merci aussi à Melem d'avoir répondu, même si c'était à coté du problème

  6. #6
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Points
    790
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Par défaut
    Il me semble que, dans les dernières normes, on peut passer un pointeur invalide à free sans le faire planter.

    J'ai un vague souvenir, mais il me semble que l'on peut :
    - passer null à free
    - libérer deux fois le même pointeur d'affilé.

    Je cherche un lien en attendant que l'un de vous me contredise...

  7. #7
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Points
    13 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Par défaut
    N1256 :
    The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

  8. #8
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Points
    8 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Par défaut
    Citation Envoyé par valefor Voir le message
    Il me semble que, dans les dernières normes, on peut passer un pointeur invalide à free sans le faire planter.

    J'ai un vague souvenir, mais il me semble que l'on peut :
    - passer null à free
    - libérer deux fois le même pointeur d'affilé.

    Je cherche un lien en attendant que l'un de vous me contredise...
    La seule manière porable de spécifier une adresse invalide en C est NULL. Si tu passes NULL à free par exemple, la foction, en remarquant que NULL (qui est une adresse invalide) est passée, ne tentera rien. Si tu passes autre chose que NULL, la fonction suppose qu'il s'agit d'une adresse valide. Si c'est bien le cas, elle fera bien son travail. Sinon (si c'est par exemple l'adresse d'une mémoire déjà librée), elle va tenter d'accéder à une mémoire invalide, et tu connais la suite.

  9. #9
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Points
    5 306
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 306
    Par défaut
    Comme l'a indiqué Thierry, tu peux trier ton tableau afin de ne libérer qu'une fois tes blocs mémoires.

  10. #10
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Points
    8 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Par défaut
    Moi je pense que le fait qu'il y ait des doublons dans un tableau de pointeurs est tout simplement due à une erreur de conception. Si on vérifiait le contenu du tableau avant d'ajouter un nouvel élément, il n'y aurait pas ce genre de problème.

  11. #11
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Points
    5 306
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 306
    Par défaut
    Citation Envoyé par Melem Voir le message
    Moi je pense que le fait qu'il y ait des doublons dans un tableau de pointeurs est tout simplement due à une erreur de conception. Si on vérifiait le contenu du tableau avant d'ajouter un nouvel élément, il n'y aurait pas ce genre de problème.
    +1

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Points
    17 923
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem Voir le message
    Moi je pense que le fait qu'il y ait des doublons dans un tableau de pointeurs est tout simplement due à une erreur de conception. Si on vérifiait le contenu du tableau avant d'ajouter un nouvel élément, il n'y aurait pas ce genre de problème.
    Citation Envoyé par vicenzo Voir le message
    +1

    Dans ce cas précis peut-être (quoiqu'on ne connaisse pas le pbe exact que veut résoudre le PO), mais cela peut souvent arriver dans du vrai code... En particulier lorsque tu as besoin d'optimisation mémoire..

    Je te cite un exemple :

    tu as un point 3D (3 coordonnées réelles), alloué dynamiquement.

    Ce point est simultanément dans un plan, un volume, et 2 lignes (cas d'un noeud d'un réseau de maillage 3D).

    Maintenant admettons que l'on utilise alternativement les formes ligne, plan, et volume. Dans chacune des 3 formes, on aura un pointeur .. identique..

    CQFD..

    PS: pour le poblème du PO, il suffit, si il ne peut ou ne veut trier son tableau, à chaque fois qu'il veut libérer une adresse, qu'il vérifie si la même existe avant...

    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
    for ( i = 0 ; i < n ; i++ )
      {
          if ( i > 0 )
            {
                DoIt = 1 ;
     
                for ( j = (i-1) ; j >= 0 ; j-- )
                   {
                        if ( tableau[j] == tableau[i] )
                          {
                               DoIt = 0 ;
                               break ;
                          }
                   }
     
                if ( DoIt )
                   {
                         free(tableau[i]);
                   }
            }
          else
                free(tableau[i]);
      }

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Par défaut
    Citation Envoyé par valefor Voir le message
    Il me semble que, dans les dernières normes, on peut passer un pointeur invalide à free sans le faire planter.
    Dans tes rêves...

  14. #14
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Points
    790
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Par défaut
    Oui bon, j'ai un peu divagué là, mais j'entendais par invalide null ou déjà libéré.

    Donc il semblerait effectivement que je me soit trompé pour un pointeur déjà libéré : il n'est défini nulle part le comportement pour ce genre d'opérations.

Discussions similaires

  1. Problème de libération de mémoire avec free()
    Par Nival dans le forum Débuter
    Réponses: 8
    Dernier message: 19/03/2009, 00h06
  2. [Mémoire] Problème de libération de mémoire
    Par CTotophe85 dans le forum C++
    Réponses: 7
    Dernier message: 24/11/2008, 13h47
  3. problème de libération de mémoire
    Par hamoudasafira dans le forum C++
    Réponses: 3
    Dernier message: 19/03/2007, 19h54
  4. Problème de libération de mémoire
    Par saturne13 dans le forum Linux
    Réponses: 9
    Dernier message: 06/02/2007, 10h18
  5. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 18h38

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