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 Delphi Discussion :

Désallouer la mémoire pour un tableau dynamique multidimensionnel


Sujet :

Langage Delphi

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2015
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2015
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Désallouer la mémoire pour un tableau dynamique multidimensionnel
    Bonjour,

    j'utilise un tableau dynamique a 3 dimensions.

    Je le déclare:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    tempResult                    : array of array of array of real;
    Je définis ces dimensions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SetLength(tempResult, nbsb, nbda,nbdtsauv);
    Puis je l'utilise dans mon programme, mais au moment de le désallouer je n'y arrive pas.
    J'ai essayé:
    -de laisser delphi le faire tout seul: ça plante
    - un finalize:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Finalize(tempResult);
    ça plante aussi
    - de mettre la taille à 0:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SetLength(tempResult,0)
    ça plante aussi

    Je suis donc un peu perdu... sauriez-vous comment désallouer ce tableau?

    Merci d'avance,

    Vincent

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par un_singe_en_hiver Voir le message
    j'utilise un tableau dynamique a 3 dimensions.
    ...mais au moment de le désallouer je n'y arrive pas.
    J'ai essayé:
    -de laisser delphi le faire tout seul: ça plante
    Quel est le message d'erreur ?

    Citation Envoyé par un_singe_en_hiver Voir le message
    - un finalize:
    ça plante aussi
    Quel est le message d'erreur ?

    Citation Envoyé par un_singe_en_hiver Voir le message
    - de mettre la taille à 0: SetLength(tempResult,0)ça plante aussi
    Et quel est le message d'erreur ?

    Ces 2 derniers cas font pourtant partie des cas possibles.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tempResult := nil;
    Finalize(tempResult);
    SetLength(tempResult, 0);
    En fait, votre problème doit se trouver ailleurs... Quelle version de Delphi ?
    Philippe.

  3. #3
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 490
    Points : 2 752
    Points
    2 752
    Billets dans le blog
    10
    Par défaut
    Je verrai plotôt quelque chose comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var
      tempResult : array of array of array of real;
    begin
      // Alloue
      SetLength(tempResult,3,4,5);
      // Remet à zero et libère
      SetLength(tempResult,0,0,0);
      FreeAndNil(tempResult) ;
    Le FreeAndNil est important si tu utilises un tableau passé par valeur à une procédure ou une fonction

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2015
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2015
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Ph. B. Voir le message

    En fait, votre problème doit se trouver ailleurs... Quelle version de Delphi ?
    Hé oui effectivement cela venait d'ailleurs je remplissais mon tableau et je débordais d'une case dans le tableau. Ce qui a fait que je ne l'ai pas vu c'est que le programme semblait réaliser cette opération et ne plantait qu'au moment de supprimer le tableau.

    Désolé pour le dérangement,

    et merci de l'aide

    Vincent

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par ALWEBER Voir le message
    Je verrai plotôt quelque chose comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var
      tempResult : array of array of array of real;
    begin
      // Alloue
      SetLength(tempResult,3,4,5);
      // Remet à zero et libère
      SetLength(tempResult,0,0,0);
      FreeAndNil(tempResult) ;
    Le FreeAndNil est important si tu utilises un tableau passé par valeur à une procédure ou une fonction
    FreeAndNil attend un objet. C'est une VA assurée ton truc
    Ca passe ici (mais est totalement inutile) parce que SetLength(0) a reset-é le pointeur.

    Comment passer un tableau dynamique par valeur C'est son pointeur uniquement qui est passé par valeur.

  6. #6
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 490
    Points : 2 752
    Points
    2 752
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    FreeAndNil attend un objet. C'est une VA assurée ton truc
    Ca passe ici (mais est totalement inutile) parce que SetLength(0) a reset-é le pointeur.

    Comment passer un tableau dynamique par valeur C'est son pointeur uniquement qui est passé par valeur.
    En fait tu as raison le freeandNil ne sert à rien mais dans l'exemple suivant arX := nil ; est essentiel
    Voici le code que j'ai du employer à la place du setlength pour réinitialiser des variables locales de type Tableau dans des procédures ou de fonctions car il y a des problèmes dans Delphi. La première fois cela se passe bien. Après cela pose des problèmes.

    En ce qui concerne le FreeAndNil je faisais référence au Record qui peut se comporter comme un Record ou une Classe suivant sa déclaration.

    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
     
    type
      TArDouble = array of double;
    ...
    procedure setlength1(var arX: TArDouble; long : integer);
    var
      i1 : integer ;
    begin
      i1 := length(arX) ;
      if i1 = 0 then
        setlength (arX, long)
      else
        if long <> i1  then
        begin
          setLength(arX,0) ;
          arX := nil ;
          Finalize(arX);
          setlength (arX, long) ;
        end ;
    end ;

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par ALWEBER Voir le message
    En fait tu as raison le freeandNil ne sert à rien mais dans l'exemple suivant arX := nil ; est essentiel
    Mais pourquoi ? Si un tableau est de longueur 0, la variable le référençant est déjà à nil. Inversement, si tu préfères écrire arX := nil, tu peux te passer du SetLength(arX, 0).

    Citation Envoyé par ALWEBER Voir le message
    Voici le code que j'ai du employer à la place du setlength pour réinitialiser des variables locales de type Tableau dans des procédures ou de fonctions car il y a des problèmes dans Delphi.
    Quel genre de problème ?

    Citation Envoyé par ALWEBER Voir le message
    En ce qui concerne le FreeAndNil je faisais référence au Record qui peut se comporter comme un Record ou une Classe suivant sa déclaration.
    Un record ne peut pas avoir de destructeur.

  8. #8
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 490
    Points : 2 752
    Points
    2 752
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Un record ne peut pas avoir de destructeur.
    Effectivement.
    Je faisais référence à cette information docwiki.embarcadero
    au chapitre "Enregistrements (avancés)" ou il est dit "le langage Delphi autorise des types enregistrement plus complexes, similaires à des classes"
    Après vérification, le constructeur "Create" sur un record ne génère pas de nouvelle structure en mémoire donc si pas de création pas de destruction.

    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
     
    ...
    {$APPTYPE CONSOLE}
    ...
    type
      T1 = record
        i1 : integer ;
      public
        constructor Create (val : integer);
      end;
    var
      v1 : T1 ;
      p1 : ^Integer ;
    constructor T1.Create(val: integer);
    begin
      i1 := val ;
    end;
     
    begin
      p1 := @v1 ;
      writeln(intToHex(integer(p1^),8)) ;
      v1.i1 := $11223344 ;
      writeln(intToHex(integer(p1),8)) ;
      writeln(intToHex(integer(p1^),8)) ;
      v1 := T1.Create($12345678) ;
      writeln(intToHex(integer(p1),8)) ;
      writeln(intToHex(integer(p1^),8)) ;
      readln;
    end.

  9. #9
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 490
    Points : 2 752
    Points
    2 752
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Mais pourquoi ? Si un tableau est de longueur 0, la variable le référençant est déjà à nil....
    .
    Le problème rencontré était dans un programme qui manipulait de nombreux tableaux et que j'ai résolu par la solution présentée. Je vais modéliser ce problème et le mettre sur ce site.

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Qui pourrait plus simplement s'écrire v1.Create($12345678);. Cette écriture-là s'apparente effectivement à une instance de classe puisque invoquer Create sur la variable a pour effet de la réinitialiser (ce qui est défini dans le constructeur bien-sûr)
    Mais sur un record, je n'ai jamais aimé ce terme de constructeur car appeler MyRecord := TMyRecord.Create(0); revient uniquement à lui copier une pseudo-constante (le record est une valeur et non une référence).

    Ça permet cependant dans certains cas une grosse simplification d'écriture. Ainsi ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function TForm1.IsIntersecting(aRect: TRect; L, T, R, B: integer): boolean;
    var
      Rect :TRect;
    begin
      Rect.Left   := L;
      Rect.Top    := T;
      Rect.Right  := R;
      Rect.Bottom := B;
     
      Result := aRect.IntersectsWith(Rect);
    end;
    peut être simplifié comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function TForm1.IsIntersecting(aRect: TRect; L, T, R, B: integer): boolean;
    begin
      Result := aRect.IntersectsWith(TRect.Create(L, T, R, B));
    end;
    Par contre, ceci est invalide (d'où le terme de pseudo-constante) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    with TRect.Create(10, 10, 100, 100) do
    begin
      Left := 50;
      ...
    end;

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 26/09/2007, 21h24
  2. Réponses: 28
    Dernier message: 27/05/2007, 15h16
  3. Quel lg et IDE pour dev 1 appli multi-plateformes?
    Par Langelot dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 03/02/2005, 23h36
  4. Economie de mémoire pour plusieur images avec la même source
    Par neness dans le forum Composants VCL
    Réponses: 5
    Dernier message: 18/01/2004, 10h56

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