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 :

Curiosité de TFileStream


Sujet :

Langage Delphi

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    486
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 486
    Points : 269
    Points
    269
    Par défaut Curiosité de TFileStream
    Bonjour
    Je découvre un comportement inexplicable de TFileStream.create. Dans le code qui 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
    17
    18
    19
     
    function  GetTempFile(Path : AnsiString):PAnsiChar;
    var s,f:string;
      SaveFile:array [0..MAX_PATH]of char;
      u:integer;
      fs:TFileStream;
    begin
         u:=Windows.GetTempFileName(PAnsiChar(Path),nil,0,SaveFile);
         if u=0 then result:='' else result:=SaveFile;
    end;
     
    procedure TForm1.Button6Click(Sender: TObject);
    var s,f:Ansistring;
      SaveFile:PAnsiChar;
      u:integer;
      fs:TFileStream;
    begin
         SaveFile:=GetTempFile(GetEnvironmentVariable('TEMP')); // Renvoie un PAnsiChar sur un nom de fichier temporaire
          fs:=TFileStream.create(SaveFile,fmOpenReadWrite);
    Le create fonctionne mais après son execution SaveFile est inacessible.

    Ce pointeur a été alloué par GetTempFileName mais pourquoi son usage le fait il disparaitre ?

  2. #2
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    ouch !

    un PChar est un pointeur sur un Char

    ta fonction retourne un pointeur sur une variable locale à la fonction.

    où se trouvent les variables locales ? dans le cas présent sur la pile.

    Qu'est-ce que la pile ? c'est une zone mémoire ou on empile les données puis les dépiles...cela permet par exemple un appel récursif d'une fonction, la pile contient alors les variables locale de chaque appel avec l'adresse de retour...quand on dépile, on prend sur la pile l'adresse retour et on libère toutes les variables locales.

    donc ta fonction GetTempFile() alloue de la place sur la pile, notamment pour SaveFile, alimente son contenu et retourne un pointeur sur cette zone mémoire...qui est considérée disponible dès la fin de la procédure.
    l'appel à TFileStream.Create va gentiment écrire sur la pile justement là où se trouve SaveFile...bon comme tu as deux autres variables avant, la valeur ne vas pas forcément être écrasée de suite, mais en tout cas les données sont dans une zone considérée comme disponible.

    il est préférable d'utiliser un string, en plus Delphi fait l'allocation automatiquement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function  GetTempFile(Path : AnsiString): string;
    var s,f:string;
      SaveFile:array [0..MAX_PATH]of char;
      u:integer;
      fs:TFileStream;
    begin
         u:=Windows.GetTempFileName(PAnsiChar(Path),nil,0,SaveFile);
         if u=0 then result:='' else result:=string(SaveFile);
    end;
    euh..Par contre je vois un mélange entre Char et AnsiChar/PAnsiChar, ce devrait être


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function  GetTempFile(const Path : string): string;
    var s,f:string;
      SaveFile:array [0..MAX_PATH]of char;
      u:integer;
      fs:TFileStream;
    begin
         u:=Windows.GetTempFileName(PChar(Path),nil,0,SaveFile);
         if u=0 then result:='' else result:=string(SaveFile);
    end;

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    486
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 486
    Points : 269
    Points
    269
    Par défaut
    Effectivement...

    A propos du mélange PAnsiChar et PChar cela vient du fait que ce code est en Delphi 7. Mais là aussi c'est plus cohérent de faire un choix constant.

    Merci

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

Discussions similaires

  1. [TFileStream] : LoadFromStream et read : incompatible ?
    Par jmdeffet dans le forum Langage
    Réponses: 4
    Dernier message: 18/11/2004, 10h30
  2. TFileStream et Array of char
    Par busy999 dans le forum Langage
    Réponses: 2
    Dernier message: 06/07/2004, 21h00
  3. TFileStream et les fichiers de plus de 2Go
    Par naikon dans le forum C++Builder
    Réponses: 3
    Dernier message: 29/06/2004, 16h11
  4. [TFileStream] Problème de lecture de string
    Par Pedro dans le forum Langage
    Réponses: 6
    Dernier message: 28/06/2004, 13h06
  5. Curiosité concernant le réseau sous mandrake 9.2
    Par R3iTt0R dans le forum Réseau
    Réponses: 4
    Dernier message: 04/06/2004, 11h57

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