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 :

Allocation de mémoire pchar


Sujet :

Langage Delphi

  1. #1
    Membre régulier Avatar de ALEX77
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 138
    Points : 76
    Points
    76
    Par défaut Allocation de mémoire pchar
    Bonjour à tous
    J'ai créé une fonction qui nettoie une chaîne de type string en enlevant les caractères #13 et #10.
    C'est beaucoup plus rapide que d'utiliser la fonction StringReplace et ça semble fonctionner correctement.
    Pour cela je passe par un pchar auquel j'alloue la quantité de mémoire nécessaire et je libère ensuite ce pointeur.
    Cependant, même si ça semble fonctionner correctement, j'ai un doute : je ne suis pas sûr que d'allouer la bonne quantité de mémoire et que mon pointeur est bien libéré lorsque je quitte ma fonction. De plus, faut-il vraiment assigner le #0 au dernier caractère ? Quelqu'un pourrait-il regarder ça et me dire si c'est ok :
    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
    function RemoveChars(source : string) : string;
    var i, n : integer;
        pSource, pCible : pchar;
    begin
     try
      pSource:= pchar(source);
      pCible:= StrAlloc(Length(source)+1);
      i:= 0;
      n:= -1;
      while not (pSource[i] = #0) do
      begin
       if (pSource[i] <> chr(13)) and (pSource[i] <> chr(10)) then
       begin
        inc(n);
        pCible[n]:= pSource[i];
       end;
       inc(i);
      end;
      pCible[n+1]:= #0;
      result:= StrPas(pCible);
     finally
      StrDispose(pCible);
     end;
    end;
    Merci pour votre aide :-)

  2. #2
    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
    Citation Envoyé par ALEX77 Voir le message
    De plus, faut-il vraiment assigner le #0 au dernier caractère ? Quelqu'un pourrait-il regarder ça et me dire si c'est ok :
    Oui, sinon StrPas risque de ne pas trouver la fin de la chaine !

    Par contre, le try devait être après le StrAlloc, cela m'étonne que cela ne signale une variable non initialisée

    StrPas provoquera au final, une réallocation de mémoire
    En D7, un coup couteux
    En D2007+, c'est indolore (FastMM étant inclus dans cette version)

    En fait, tu n'utilises pas le PChar au maximum !
    Tu conserves les offsets [i] et [n] alors que l'utilisation du PChar permet juste de supprimer l'arithmétique des pointeurs liés au tableau
    Voici une version XE2 uniquement à base de SetLength (c'est lui fait l'allocation nécessaire puis la réduction de la taille de chaine)

    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
    function RemoveChars(const ASource: string) : string;
    var
      pSource, pCible, pCibleS: PChar;
    begin
      pSource := PChar(ASource);
     
      SetLength(Result, Length(ASource));
      pCibleS := PChar(Result);
      pCible := pCibleS;
     
      while pSource^ <> #0 do
      begin
        if (pSource^ <> chr(13)) and (pSource^ <> chr(10)) then
        begin
          pCible^ := pSource^;
          Inc(pCible);
        end;
        Inc(pSource);
      end;
      SetLength(Result, pCible - pCibleS);
    end;
    Sinon, si tu veux améliorer ta fonction, regarder dans Comment supprimer tous les caractères spéciaux d'une string ?
    Soit DeleteFromStr, on supprime ce qu'il y en trop (ton cas avec juste #13 #10)
    Soit CopyStringOnly, on ne conserve que ce qui est prévu

    A lire les optimisations dans Y-a-t-il plus rapide pour enlever les accents ?

  3. #3
    Membre régulier Avatar de ALEX77
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 138
    Points : 76
    Points
    76
    Par défaut
    Merci pour ta réponse et pour les liens.
    En fait je suis en train de parser un fichier RTF pour y trouver les sections, (entêtes, pied de page, texte principal, et... images) et je cherchais un moyen de faire cela assez rapidement.
    J'arrive à lire pour l'instant le .doc, le .docx, le .odt et maintenant le .rtf

    La prochaine étape sera de pouvoir extraire le texte et les images d'un PDF (si tu as des infos là-dessus ça m'intéresserait énormément car je galère avec ce format qui n'est pas si évident à lire et dont la mise en page est complexe).

    Sinon, je suis sous D2007 j'ai testé 2 méthodes et je dois dire qu'elles sont aussi rapides :

    La première (celle du lien) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function DeleteFromStr(const Str : string; Excluded : TSysCharSet) : string;
    var Len, I, J : integer;
    begin
     Len := Length(Str);
     SetLength(Result, Len);
     J := 0;
     for I := 1 to Len do if not (Str[i] in Excluded) then
     begin
      inc(J);
      Result[J] := Str[i];
     end;
     SetLength(Result, J);
    end;
    Et celle que tu as modifié pour moi dans ton code ci-desus à laquelle j'ai ajouté chars_to_remove :
    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
    function RemoveChars(const ASource: string; chars_to_remove : TSysCharSet) : string;
    var pSource, pCible, pCibleS: PChar;
    begin
     pSource := PChar(ASource);
     
     SetLength(Result, Length(ASource));
     pCibleS := PChar(Result);
     pCible := pCibleS;
     
     while pSource^ <> #0 do
     begin
      if not (pSource^ in chars_to_remove) then
      begin
       pCible^ := pSource^;
       Inc(pCible);
      end;
      Inc(pSource);
     end;
     SetLength(Result, pCible - pCibleS);
    end;
    Les deux fonctions sont aussi rapides l'une que l'autre donc c'est du bon :-)

    Merci ;-)

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

Discussions similaires

  1. [debutant] : Allocation de mémoire dynamique
    Par sam.fet dans le forum Langage
    Réponses: 5
    Dernier message: 15/02/2006, 14h58
  2. Problème d'allocation de mémoire dans la pile
    Par prophet666 dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 19/01/2006, 02h22
  3. [Debutant]Allocation de mémoire
    Par gwendal84 dans le forum C
    Réponses: 6
    Dernier message: 07/12/2005, 19h04
  4. Double allocation de mémoire
    Par hunter001 dans le forum C++
    Réponses: 16
    Dernier message: 25/08/2005, 13h53
  5. pb d'allocation de mémoire
    Par shura dans le forum C
    Réponses: 7
    Dernier message: 17/04/2005, 21h10

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