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

Langage Pascal Discussion :

Libération de pointeurs d'une liste doublement chaînée


Sujet :

Langage Pascal

  1. #1
    Membre régulier
    Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 101
    Points : 80
    Points
    80
    Par défaut Libération de pointeurs d'une liste doublement chaînée
    Bonjour à toutes et à tous.
    Dans une liste doublement chaînée, un seul pointeur permet de parcourir toute la liste dans un sens ou dans l'autre. A la fermeture du programme, faut-il libérer les pointeurs de chaque enregistrement de la liste ou un seul d'entre eux ? Faut-il vider (nil pour les deux pointeurs, chaînes vides pour les string, annuler les entiers et réels...) chaque élément de chaque enregistrement ? Quelles sont les conséquences en termes de fonctionnement de l'ordinateur si cela n'est pas fait ?
    Merci d'avance pour vos réponses et conseils.

  2. #2
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Attention, un pointeur est un type de variable qui contient l'adresse de début d'une zone mémoire. Un pointeur n'est pas de la mémoire, donc dire "libérer un pointeur" est un peu incorrect. Il faudrait plutôt dire "libérer la zone mémoire pointée par le pointeur".

    Tout ça pour dire: une liste chaînée est une liste de pointeurs, qui pointent chacun sur des zones mémoire différentes. Quand tu libères ta chaîne entière, tu dois donc libérer chaque zone pointée par les pointeurs formant la chaîne, et non pas qu'un seul.

    L'impact sur la machine, c'est qu'il reste de la mémoire allouée, qui ne peut pas être utilisée par la suite par les autres programmes. C'est la théorie, car en pratique, je ne suis pas certain que cela reste vrai avec les operating systems modernes que sont entre autres Windows et Linux.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    pour faire simple, je dirais qu'il faut libérer ce qui a été alloué...

    je m'explique par un exemple:
    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
     
    var
      Data: array [0..100] of TData;
      First: PData;
      Item: PData;
      i     : Integer;
    begin
      First := nil;
      for i := 0 to 100 do
      begin
        Item := @Data[i];
        Item.Next := First;
        First := Item;
      end;
    end;
    dans le code ci-dessus j'ai une liste chaînée avec des pointeurs sur des structures allouées statiquement...je n'ai donc rien à libérer

    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
     
    type
      TItem = class
        Prev: TItem;
        Next: TItem;
      end;
    var
      First: TItem;
      Item: TItem;
      Last: TItem;
      i : Integer;
    begin
      First := nil;
      for i := 0 to 10 do
      begin
        Item := TItem.Create;
        if First = nil then
          First := Item
        else
          Last.Next := Item;
        Last := Item;
      end;
    //...
      while First <> nil do
      begin
        Item := First;
        First := Item.Next;
        Item.Free;
      end;
    end;
    ici on a une double liste chaînée, pour la libérer, il faut détruire (une fois évidemment) chaque noeud...on peut parcourir la liste dans un sens ou dans l'autre, mais une seule fois.

    Note que tes éléments peuvent aussi faire parti de plusieurs listes chaînées, là encore il ne faut les libérer qu'une fois et supprimer les références dans les autres listes.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre régulier
    Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 101
    Points : 80
    Points
    80
    Par défaut
    Bonjour à toutes et à tous.
    Merci pour les réponses déjà fournies.
    Je comprends la nécessité de libérer la mémoire dans une procédure ou un programme pour éviter l'erreur "Out of memory". Mais que se passe-t-il à la sortie de cette procédure ou de ce programme ?
    J'aimerais connaître la quantité de mémoire allouée à l'entrée et à la sortie d'une procédure (ou d'un programme) où est définie localement une liste doublement chaînée. Quelles sont les fonctions permettant cela en Free Pascal et quelle est l'unité où elles sont définies? Dans Delphi il me semble que les fonctions AllocMemCount et AllocMemSize le permettent.
    Merci d'avance pour votre aide.

  5. #5
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Il me semble que AllocMemSize et AllocMemCount ne sont pas disponible sur FreePascal. Tu peux regarder GetHeapStatus:

    http://www.freepascal.org/docs-html/...eapstatus.html


    Sinon, tu peux faire le calcul par toi même. Un pointeur dans un monde 32 bits fait 4 octets, il te suffit de calculer la taille de la structure stockée dans la liste chaînée, multiplier par le nombre d'éléments, et tu as la taille de la liste en mémoire.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

Discussions similaires

  1. Copier une partie d'une liste doublement chaînée
    Par ChrisNilson dans le forum Débuter
    Réponses: 10
    Dernier message: 08/12/2013, 03h41
  2. Réponses: 1
    Dernier message: 23/03/2013, 13h26
  3. Déplacement dans une liste doublement chaînée
    Par Adenora dans le forum Débuter
    Réponses: 9
    Dernier message: 19/10/2010, 15h43
  4. Réponses: 9
    Dernier message: 14/01/2007, 17h09

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