1. #1
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 190
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 190
    Points : 8 449
    Points
    8 449

    Par défaut GetMem/FreeMem, un couple en instance de divorce ?

    Salut,

    Nouvelle semaine, nouvelles blagues et donc, rions un peu avec d'un côté la théorie et tout ce qu'on nous apprend sur l'allocation de mémoire et sa libération (exemple extrait de l'aide Lazarus :
    Nom : ex_getfreemem.png
Affichages : 30
Taille : 11,9 Ko
    ), et d'un autre côté la pratique et sa mise en application dans la vraie vie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type
      TPointeurDeLigne = array[0..359] of TColor;
      pPointeurDeLigne = ^TPointeurDeLigne;
    var
      PointeurDeLigne: pPointeurDeLigne;
    begin
      GetMem(PointeurDeLigne, 360 * SizeOf(TColor));// mémoire pour 1 ligne
      // utilisation parfaite, c'est pour générer un dégradé en mode Scanline
      // et juste avant de sortir de la proc (image affichée ok, bmp libéré, etc.)
      // bim ! paf ! boum !
      FreeMem(PointeurDeLigne, 360 * SizeOf(TColor)); // idem
    end;

    C'est lassant la programmation, des fois...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    4 449
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 4 449
    Points : 9 078
    Points
    9 078

    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    GetMem(PointeurDeLigne);
    Inc(PointeurDeLigne);
    FreeMem(PointeurDeLigne);
    Rien ne te choque ?

    Tu réserves 360 emplacements et tu avances de 360. Tu tentes donc une libération de 361 à 720...

  3. #3
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    avril 2002
    Messages
    2 417
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : avril 2002
    Messages : 2 417
    Points : 4 101
    Points
    4 101

    Par défaut

    Citation Envoyé par Andnotor Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    GetMem(PointeurDeLigne);
    Inc(PointeurDeLigne);
    FreeMem(PointeurDeLigne);
    Rien ne te choque ?

    Tu réserves 360 emplacements et tu avances de 360. Tu tentes donc une libération de 361 à 720...
    Désolé je vois pas le inc() dans le code plus haut.

    Jipété, tu déclares un type que tu n'utilises jamais -> A quoi ça sert ?
    Théoriquement, j'aurais plutôt écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GetMem(PointeurDeLigne, SizeOf(TPointeurDeLigne));
    FreeMem(PointeurDeLigne, SizeOf(TPointeurDeLigne));
    Si tu n'es pas sûr de la taille de ton objet, il vaut mieux laisser faire le compilateur.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  4. #4
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 190
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 190
    Points : 8 449
    Points
    8 449

    Par défaut

    Citation Envoyé par M.Dlb Voir le message
    Jipété, tu déclares un type que tu n'utilises jamais -> A quoi ça sert ?

    Si tu n'es pas sûr de la taille de ton objet, il vaut mieux laisser faire le compilateur.
    Je n'avais pas mis la cuisine interne et l'utilisation vis-à-vis du bitmap pour alléger.

    Du coup ça m'a mis la puce à l'oreille, et j'ai fait ce test avec juste ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    begin
      GetMem(PointeurDeLigne, 360 * SizeOf(TColor));// mémoire pour 1 ligne
      FreeMem(PointeurDeLigne, 360 * SizeOf(TColor));
    end;
    et ça ne plante pas.
    PS : je suis sûr de la taille de mon objet, voir le commentaire en bout de ligne GetMem.

    À force de décommentages () des lignes commentées, je cerne le problème autour de cette ligne (y a pas tout, c'est le cœur du remplissage du TBitmap) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          BeginUpdate;
          for h := 0 to 100 do begin // balayage vertical
            PointeurDeLigne := pPointeurDeLigne(RawImage.GetLineStart(h)); // avec cette ligne présente, AV au FreeMem + bas
            // for w := 0 to 359 do PointeurDeLigne^[w] := LCH2Color(h, trkPos, w, true); // ma proc pour générer les couleurs
          end;
          EndUpdate();
    Si qqun a une idée, ça m'intéresse.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    4 449
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 4 449
    Points : 9 078
    Points
    9 078

    Par défaut

    Je pense déjà avoir répondu : le pointeur après utilisation ne correspond plus à l'adresse d'origine. Après, que le pointeur soit incrémenté par inc ou toute autre méthode importe peu

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var
      pOrigine :pointer;
      PointeurDeLigne: pPointeurDeLigne;
     
    begin
      GetMem(pOrigine, 360 * SizeOf(TColor));
      PointeurDeLigne := pOrigine;
     
      //Utilisation de PointeurDeLigne
     
      FreeMem(pOrigine);
    end;

  6. #6
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 190
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 190
    Points : 8 449
    Points
    8 449

    Par défaut

    Citation Envoyé par Andnotor Voir le message
    Je pense déjà avoir répondu
    Oui mais c'était en mode ésotérique, subliminal, codé à l'économie de mots et écrit à l'encre sympathique

    Bien joué, t'es le plus fort
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    4 449
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 4 449
    Points : 9 078
    Points
    9 078

    Par défaut

    Pas plus que la donnée qui une fois les commentaires nettoyés est pour le moins succincte. Boule de Crystal obligatoire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    GetMem(PointeurDeLigne, 360 * SizeOf(TColor));
    // bim ! paf ! boum !
    FreeMem(PointeurDeLigne, 360 * SizeOf(TColor));
    Et à noter encore que spécifier la taille sur FreeMem est optionnel si le bloc complet est libéré.

  8. #8
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 190
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 190
    Points : 8 449
    Points
    8 449

    Par défaut

    Citation Envoyé par Andnotor Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var
      pOrigine :pointer;
      PointeurDeLigne: pPointeurDeLigne;
     
    begin
      GetMem(pOrigine, 360 * SizeOf(TColor));
      PointeurDeLigne := pOrigine;
     
      //Utilisation de PointeurDeLigne
     
      FreeMem(pOrigine);
    end;
    Ah tiens, tout-à-l'heure j'ai passé mon code de Lazarus à D7, 2-3 adaptations mineures mais dans l'ensemble ça roule, juste ce message du compilo qui m'interpelle, à propos de la ligne 7 :
    Citation Envoyé par compilo D7
    [Conseil] : La valeur affectée à 'PointeurDeLigne' n'est jamais utilisée
    Mais pourquoi les compilateurs ne sont jamais contents
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    4 449
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 4 449
    Points : 9 078
    Points
    9 078

    Par défaut

    Tu as certainement deux affectations PointeurDeLigne := ... sans aucun traitement sur la première. Le compilateur attire ton attention pour éventuellement te permettre de nettoyer/alléger le code.

  10. #10
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 190
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 190
    Points : 8 449
    Points
    8 449

    Par défaut

    Citation Envoyé par Andnotor Voir le message
    Tu as certainement deux affectations PointeurDeLigne := ... sans aucun traitement sur la première.
    Si tu vois où, ça m'arrange parce que moi, je donne ma langue au chat :
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      pOrigine: pointer;  // ajout Andnotor /!\ +1 /!\
      PointeurDeLigne: pPointeurDeLigne;
      h,w: Integer;
      aBmp: TBitmap;
    begin
      GetMem(pOrigine, 360 * SizeOf(TColor)); // mémoire pour 1 ligne
      PointeurDeLigne := pOrigine;  // ajout Andnotor /!\ +1 /!\
     
      aBmp := TBitmap.Create;
      with aBmp do begin
        try
          PixelFormat := pf32bit;
          Width  := 360;
          Height := 101;
          for h := 0 to 100 do begin
            PointeurDeLigne := pPointeurDeLigne(Scanline[h]); // [Conseil] : La valeur affectée à 'PointeurDeLigne' n'est jamais utilisée
            for w := 0 to 359 do PointeurDeLigne^[w] := newLCH2Color(50, 50, w);
          end;
          Image3.Picture.Graphic := aBmp;
        finally
          Free;
        end;
      end;
      FreeMem(pOrigine);
    end;
    Ou alors c'est sur la ligne 18 ? Mais comment faire autrement ?
    Merci,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  11. #11
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    6 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 6 827
    Points : 21 830
    Points
    21 830

    Par défaut

    il suffit de supprimer quelques petites lignes

    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
    //  pOrigine: pointer;  // ajout Andnotor /!\ +1 /!\
      PointeurDeLigne: pPointeurDeLigne;
      h,w: Integer;
      aBmp: TBitmap;
    begin
    //  GetMem(pOrigine, 360 * SizeOf(TColor)); // mémoire pour 1 ligne
    //  PointeurDeLigne := pOrigine;  // ajout Andnotor /!\ +1 /!\
     
      aBmp := TBitmap.Create;
      with aBmp do begin
        try
          PixelFormat := pf32bit;
          Width  := 360;
          Height := 101;
          for h := 0 to 100 do begin
            PointeurDeLigne := pPointeurDeLigne(Scanline[h]); // [Conseil] : La valeur affectée à 'PointeurDeLigne' n'est jamais utilisée
            for w := 0 to 359 do PointeurDeLigne^[w] := newLCH2Color(50, 50, w);
          end;
          Image3.Picture.Graphic := aBmp;
        finally
          Free;
        end;
      end;
    //  FreeMem(pOrigine);
    end;
    ton allocation ne sert strictement à rien puisque tu veux manipuler les pixels du bitmap qui a DEJA alloué sa mémoire
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal

  12. #12
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 190
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 190
    Points : 8 449
    Points
    8 449

    Par défaut

    Citation Envoyé par Paul TOTH Voir le message
    il suffit de supprimer quelques petites lignes
    Parfaitement fonctionnel sous Lazarus/Linux, je testerai à l'occasion sous D7perso (ton livre )/Win2000.

    Merci et bonne journée,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/10/2003, 11h22
  2. Communiquer entre plusieurs instances d'applications
    Par bourinator dans le forum C++Builder
    Réponses: 5
    Dernier message: 28/09/2003, 12h24
  3. [VB6] [DLL] DLL à instance unique
    Par HPJ dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 19/09/2003, 09h07
  4. [VB6]Passer le focus à une instance précedente
    Par Jeremiah dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 16/09/2003, 11h01
  5. [] plusieurs instances de form avec leur contexte ?
    Par Seb-31 dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 11/04/2003, 14h56

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