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

Delphi Discussion :

Tableaux dynamiques dans un record


Sujet :

Delphi

  1. #1
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    147
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 147
    Points : 38
    Points
    38
    Par défaut Tableaux dynamiques dans un record
    Bonjour


    Je suspecte un de mes programmes de planter à cause du fait que j'ai
    j'utilise un type record contenant des champs tableaux dynamiques.


    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
     
     
    Type
    TMatriceD	=	array of array of Double;
    TVecteurD	=	array of Double;
    TMatriceI	=	array of array of Integer;
    TVecteurI	=	array of Integer;
    TVecteurS	=	array of String;
     
    CodageChamp=record
     
       TableLibelleChamp:TVecteurS;
       TableIndiceChamp: TVecteurI;
       NbCodageAlpha:Integer;
       MinCodageNumerique:Double;
       MaxCodageNumerique:Double;
       ColonneTableau:Integer;
     
    end;
    De fait, la question pour moi n'est pas claire. Est-ce qu'un record supporte
    ce type de champ ou pas (avec tout ce que cela implique et notamment
    l'utilisation de setLength pour changer la taille du tableau etc.) ?


    Cordialement

    Eric

  2. #2
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Je ne pense pas qu'il y ait de problème à cela.

    Il faut juste être conscient que les données des tableaux dynamiques ne sont pas contenues dans le record, le record contient juste une référence sur ces données.

    --> Sauver en bloc le record (comme on pouvait le faire à une certaine époque), ne sauvera pas les données des tableaux dynamiques.
    --> la taille du record (SizeOf), ne donnera la taille en prenant en compte la taille des références des tableaux, et non la taille des contenus

  3. #3
    Membre confirmé
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Points : 647
    Points
    647
    Par défaut
    Bonjour.

    --> Sauver en bloc le record (comme on pouvait le faire à une certaine époque), ne sauvera pas les données des tableaux dynamiques.
    --> la taille du record (SizeOf), ne donnera la taille en prenant en compte la taille des références des tableaux, et non la taille des contenus
    Il n'y a aucun problème pour utiliser des tableaux dynamiques dans une structure (type Record) à l'exception des fichiers.
    Pour être enregistrée dans un fichier, une structure doit avoir une taille connue à l'avance et fixe.
    Voir mon article sur l'utilisation des fichiers.

  4. #4
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par Eric Beaumard
    Je suspecte un de mes programmes de planter à cause du fait que j'ai j'utilise un type record contenant des champs tableaux dynamiques.
    Que veut tu dire par planter ? Le tableau dynamique, par définition, a une longueur variable. Conséquement il arrive qu'on tente d'accéder à une position du tableau qui dépasse ses limites (tenter d'accéder à la 11e position d'un tableau de longueur 10 par exemple).

  5. #5
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    Citation Envoyé par slimjoe
    Que veut tu dire par planter ? Le tableau dynamique, par définition, a une longueur variable. Conséquement il arrive qu'on tente d'accéder à une position du tableau qui dépasse ses limites (tenter d'accéder à la 11e position d'un tableau de longueur 10 par exemple).
    Petit conseil : si ton problème vient de là, Eric Beaumard, je te conseille que à chaque fois que tu redimenssionne ton tableau, ajoute 1 ou 2 de dimension :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetLength(MonTableau, Dim+1);
    Ca évite les erreurs logiques, dans des boucles par exemple, qui provoquent des violation d'accès à l'addresse ... mais je penses que tu connais ça ...

  6. #6
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Citation Envoyé par Matt2094
    Petit conseil : si ton problème vient de là, Eric Beaumard, je te conseille que à chaque fois que tu redimenssionne ton tableau, ajoute 1 ou 2 de dimension :
    Code :

    SetLength(MonTableau, Dim+1);

    Ca évite les erreurs logiques, dans des boucles par exemple, qui provoquent des violation d'accès à l'addresse ... mais je penses que tu connais ça ...
    @Matt2094
    Alors là...
    c'est la 1ere fois que je l'entends celle là
    on n'ajoute pas des celulle comme ca, pour eviter les violation parcequ'il y en a une.
    Il faut être maitre du nombre de cases, et des parcours que l'on fait dans les tableaux, sinon ou va-t-on ?
    Meme si dans ce cas précis ca devait marcher, c'est qu'il y a une itération de trop ou le tableau n'est pas assez grand, mais il faut comprendre pourquoi.

    Je ne ferait pas confiance a une augmentation de taille sans en comprendre la raison exact, ou alors c'est la porte ouverte à d'autres bugs.

  7. #7
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par TicTacToe
    Je ne ferait pas confiance a une augmentation de taille sans en comprendre la raison exact...
    Moi non plus !

    EN tout cas tu dois avoir un access violation quelque part, c'est sur...

    Saches simplement que ton tableau est indicé de 0 à N-1, et que tu dois surement y accéder avec un indice de N à un moment donné.
    Saches aussi, que ce n'est pas forcément au moment où tu lis les données hors du tableau que l'Access Violation va se produire (sans doute à cause du caractère dynamique du tableau), mais plutot au retour de la procédure dans laquelle s'est produit l'accès, voir, même, carrément lorsque tu quittes ton programme.

    illustration :

    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
    function TraiteTableau(Tab:array of integer):integer;
    var i:integer;
    begin
      i:=Tab[10]; //<--acces hors du tableau qui ne produit 
                      //pas forcément l'access violation
      result:=i*i;
    end;
     
    procedure UneProcedure;
    var MonTab:array of integer;
         UnCarre:integer;
    begin
      ...
      SetLength(MonTab,10);  //<- le tableau est indicé de 0 à 9 !
      UnCarre:=TraiteTableau(MonTab);
      ShowMessage(InttoStr(UnCarre)); //L'Access violation peut très bien se produire ici !!!
      ...
    end;

  8. #8
    Membre habitué
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 151
    Points
    151
    Par défaut
    Salut
    Lorsque l'enregistrement est créé dynamiquement ( en supposant que c'est le cas... ) avec un GetMem(), il faut l' initialiser avec un FillChar() sinon effectivement vous aurez ce genre de problème.
    Le bloc de mémoire correspondant aux "types dynamiques" ( ansistring, array dynamique ) doivent être toujours bien initialisé car ce ne sont que des pointeurs déguisés. Le code ci-dessous montre que le champ chaine "s" avant initialisation contient une valeur; Ce qui est forcement erroné, décommenter la ligne en commentaire et vous verez. Pour éviter le bésoin d'initialisation utiliser New() et Dispose().
    A+
    Code Delphi : 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
     
    type
      PR = ^TR;
      TR = record
        a : Integer;
        s : ansistring;
      end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
      p : PR;
    begin
      GetMem(p,SizeOf(TR));
      try
        Memo1.Lines.Add(IntToStr(p^.a));
        Memo1.Lines.Add(IntToStr(Integer(Pointer(p^.s))));
        //Memo1.Lines.Add(p^.s); <<< Cette ligne plantera !!
        FillChar(p^,SizeOf(TR),#0);
        Memo1.Lines.Add(IntToStr(p^.a));
        Memo1.Lines.Add(IntToStr(Integer(Pointer(p^.s))));
      finally
        Freemem(p);
      end;
    end;

  9. #9
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 435
    Points : 5 848
    Points
    5 848
    Par défaut
    salut

    pour parcourir un tableau en etant sur de ne pas depassé les borne il suffit d'utiliser les methode low et higth

    @+ phil

Discussions similaires

  1. tableaux dynamiques dans arguments d'appels
    Par Infra_Red dans le forum Fortran
    Réponses: 8
    Dernier message: 24/07/2013, 23h46
  2. Réponses: 7
    Dernier message: 24/11/2006, 09h56
  3. Réponses: 1
    Dernier message: 23/06/2006, 11h19
  4. organisation de tableaux dynamiques dans une page HTML
    Par fallered dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 24/10/2005, 16h04
  5. [D7] Tableaux dynamiques dans un record
    Par bobby-b dans le forum Langage
    Réponses: 2
    Dernier message: 30/06/2004, 23h23

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