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 :

strToIntDef et erreur "Violation d'acces.."


Sujet :

Langage Delphi

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 12
    Points : 8
    Points
    8
    Par défaut strToIntDef et erreur "Violation d'acces.."
    Bonjour,

    J'ai eu un problème quand je voulais convertir 1 string en byte en utilisant strToIntDef

    J'ai une fonction comme suit :
    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
     
    type
    TString5 = String[5];
     
    //pour info octetsByBloc: array of byte;
     
    function SetTons(index:integer; value:TString5 )
    var
    i:integer;
     
    begin
      for i:=0 to 4 do
      begin
        octetsByBloc[Index+i]:= strToIntDef('$'+Value[i+1],$FF);
      end;
    end;
    Quand j'appelle par exemple SetTons(6,'31234') ou SetTons(6,'') elle marche très bien. J'ai bien eu $FF dans octetsByBloc si "value" est une chaine vide.

    Maintenant si je réécris la fonction SetTons pour qu'elle devient plus générique :

    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
     
    type
    TString5 = String[5];
     
    //pour info octetsByBloc: array of byte;
     
    procedure SetTons(index:integer; value:string; nbre:integer)
    var
    i:integer;
     
    begin
      for i:=0 to nbre-1 do
      begin
        octetsByBloc[Index+i]:= strToIntDef('$'+Value[i+1],$FF);
      end;
    end;
     
    procedure Set5Tons(index:integer; value:TString5)
    begin
      SetTons(index, value, 5);
    end;
    Quand j'appelle Set5Tons(6, ''), j'ai eu l'erreur "Violation d'access ..." alors que c'est quasiment la même fonction ?!

    Avez vous une idée...?

    Merci beaucoup,

    VR

  2. #2
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Salut,

    Dans l'une des fonctions, value est déclarée en TString5, et de l'autre, en string ...
    Je ne sais pas si c'est "fait exprès" ... mais je ne pense pas

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Merci pour ta réponse rapide
    D'après toi, le fait de déclarer string5 / string pose le problème ?!

    En fait, le but est de pouvoir réutiliser la fonction SetTons, je vais ajouter par exemple les fonctions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure Set3Tons(index:integer; value:TString3)
    begin
      SetTons(index, value, 3);
    end;
     
    procedure Set2Tons(index:integer; value:TString2)
    begin
      SetTons(index, value, 2);
    end;
    Dans ce cas là, elles ne marcherons pas alors ?
    Est-ce qu'il y a une solution pour faire ce que je voulais ?

    Merci bcp,
    VR

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Attention, une chaine courte passé à une chaine longue, ça doit être rigolo en mémoire, peut-être utiliser Length ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure SetTons(index:integer; const value:string; nbre:integer)
    var
      i:integer;
    begin
      for i:=1 to Length(value) do
        if (i <= nbre) and (('0' <= Value[i]) and (Value[i] <= '9') )then
          // octetsByBloc[Index+i-1]:= StrToIntDef('$'+Value[i],$FF) // finalement tu n'as que 0 à 9 ...
          octetsByBloc[Index+i-1]:= Ord(Value[i]) - Ord('0')
        else
          octetsByBloc[Index+i-1]:= $FF
    end;
    Pour les chaines courtes, il faut les remplir avec des espaces pour que Length renvoie 5 sinon Lengh ne renverra que le nombre de caractères définis !

    Ensuite, octetsByBloc je suppose que c'est un tableau à base 0 et que tu as fait un SetLength suffisant ?

    donc octetsByBloc pouvant aller de 6 à 10 comme index, tu as fait soit un SetLength(11) soit déclarer un tableau statique [0..10]

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 761
    Points : 13 368
    Points
    13 368
    Par défaut
    Disons que la chaîne courte, même vide, fait bien la longueur définie. Alors qu'une string, si vide, le pointeur vaut nil

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Tu as moins de risquer de déborder, mais que fait-il lors du passage en paramètre d'une chaine courte à une chaine longue ?

    il passe la référence, et donc pas de soucis, tant qu'il n'y pas de modification, on peut accéder à la mémoire sans soucis, mais après un Copy-On-Write là, ça ne doit pas être la même chose, ça me semblerait très vilain

    ou

    il copie la chaine courte dans une chaine longue, donc comportement totalement différent, et risque de VA, si l'on tente d'accéder à un caractère qui existe virtuellement dans la chaine courte (puisque buffer fixe) mais pas dans la chaine longue

    je penche pour la seconde solution, rien que pour l'histoire du Compteur de Référence et la Longueur que n'est pas géré de la même façon ...

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 761
    Points : 13 368
    Points
    13 368
    Par défaut
    La chaîne courte sera transférée dans une chaîne longue. La chaîne courte étant vide, le pointeur de la chaîne longue sera... nil. Il n'y a, à mon avis, pas de différence !

    Dans son cas, il faudrait plutôt reseter le tableau (quelque chose comme FillMemory(@octetsByBloc[Index], Length(Value), $FF)) pour ensuite ne faire la boucle que sur la longueur de la chaîne réelle.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Là....je comprend mieux, merci beaucoup

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    @ShaiLeTroll: je note la solution que t'as proposé ah "value" n'accepte que les valeurs de 0-9, le test a été fait avant d'appeler SetTons

    sinon pour la fonction SetTons, si je la modifie comme ci-dessous, qu'en pensez vous ?
    Note: "octetsByBloc" ne dépend pas la taille de value mais c'est un tableau statique [0..200]

    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
     
    procedure SetTons(index:integer; value:string; nbre:integer)
    var
    i:integer;
     
    begin
      //met $FF comme valeur par défaut
      for i:=0 to nbre-1 do
      begin
        octetsByBloc[Index+i]:= $FF;
      end;
     
      //test la chaine vide
      if (value = '') then exit;
     
      //convert chaine en Hex
      for i:=1 to length(value) do
      begin
        octetsByBloc[Index+i-1]:= strToIntDef('$'+Value[i],$FF);
      end;
    end;
    Merci,

    VR

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 761
    Points : 13 368
    Points
    13 368
    Par défaut
    Oui, c'est bon

    Je remplacerais éventuellement cette boucle d'effacement par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FillMemory(@octetsByBloc[Index], nbre, $FF)
    Mais c'est du détail !

    Un test peut être en début de routine pour s'assurer que la taille du tableau est suffisante (On sait jamais)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if Index +nbre -1 > high(octetsByBloc) then Exit;
    Tu peux également supprimer ce test sur la longeur de chaîne. Une boucle for i := 1 to 0 ne sera de toute façon pas exécutée

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    merci beaucoup pour votre aide

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

Discussions similaires

  1. Erreur de violation d'accès
    Par alvinleetya dans le forum OpenCV
    Réponses: 2
    Dernier message: 02/10/2012, 15h28
  2. Réponses: 7
    Dernier message: 10/01/2007, 09h02
  3. Réponses: 6
    Dernier message: 30/12/2006, 15h18
  4. [BSD 2006] Erreur de violation d'accès sur un ShowModal
    Par doudoustephane dans le forum C++Builder
    Réponses: 36
    Dernier message: 14/10/2006, 12h10
  5. [D7] Erreur de violation d'accès
    Par plante20100 dans le forum Langage
    Réponses: 10
    Dernier message: 26/08/2005, 11h05

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