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 :

Une incroyable erreur mémoire.


Sujet :

Delphi

  1. #1
    Membre régulier

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 540
    Points : 123
    Points
    123
    Par défaut Une incroyable erreur mémoire.
    Bonjour à tous

    Je suis bien dans la panade, là...

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // Déclaration :
      Lst_Noms_Proc : TStringList;
    Puis la procédure (qui fonctionne nickel dans un autre module EXE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Procedure Init_Lst_Noms_Proc;
    begin
     
      Var_Glob.Lst_Noms_Proc.Create;
     
      Lst_Noms_Proc.Add('RESUME PATIENTS'); // Resume_Nb_Patients;
      Lst_Noms_Proc.Add('MASSE CRITIQUE'); // Masse_Critique;
      Lst_Noms_Proc.Add('TOUS GARCONS');  // Tous_G_Sci_Et_Non_Sci;
      Lst_Noms_Proc.Add('TOUTES LES FILLES'); // Toutes_F_Sci_Et_Non;
     
      // etc.
    Je compile, mais, à l'exécution, j'ai ça :

    https://up.security-x.fr/file.php?h=...800998ecf8427e

    Le module est appelé via un create process du module EXE principal.
    Et... je ne sais vraiment pas que faire !

    Merci pour toute aide

  2. #2
    rbh
    rbh est déconnecté
    Membre confirmé Avatar de rbh
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    384
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 384
    Points : 473
    Points
    473
    Par défaut
    Salut !
    Remplace "Var_Glob.Lst_Noms_Proc.Create;" par "Var_Glob.Lst_Noms_Proc := TStringList.create;"

  3. #3
    Membre régulier

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 540
    Points : 123
    Points
    123
    Par défaut
    OK. Merci ! Je vais tenter le coup et donne le retour.
    Parce que, dans le module interne Var_Glob.pas, ça ne fonctionne pas non plus...

  4. #4
    Membre régulier

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 540
    Points : 123
    Points
    123
    Par défaut Ca marche mieux.
    Citation Envoyé par rbh Voir le message
    Salut !
    Remplace "Var_Glob.Lst_Noms_Proc.Create;" par "Var_Glob.Lst_Noms_Proc := TStringList.create;"
    Effectivement, je crée et remplis ma StringList.

    A moi, maintenant, de remplir un CheckListBox avec elle.
    Ce qui se fait très bien dans un autre module EXE... mais pas celui-là !

    En tous cas, merci ! :hello:

  5. #5
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 876
    Points : 11 365
    Points
    11 365
    Billets dans le blog
    6
    Par défaut
    A moi, maintenant, de remplir un CheckListBox avec elle.
    Comme ça : CheckListBox1.Items.Assign(Var_Glob.Lst_Noms_Proc); ?

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 612
    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 612
    Points : 25 303
    Points
    25 303
    Par défaut
    Citation Envoyé par rbh Voir le message
    Salut !
    Remplace "Var_Glob.Lst_Noms_Proc.Create;" par "Var_Glob.Lst_Noms_Proc := TStringList.create;"
    Ne sous-estimez pas cette réponse.
    Cela dépend de la version du compilateur, des options de débogage, parfois même du mode de lancement.

    Lst_Noms_Proc peut contenir une valeur aléatoire.
    Curieusement en DEBUG avec une programme lancé en Débogage, il y a plus de chance que la valeur aléatoire soit $000000000, en 32Bits, ... en 64Bits semble que cela produise aussi mais c'est moins fréquent.
    Du coup, le compilateur tente d'appeler la méthode Create sur l'instance à l'adresse mentionnée ce qui provoque presque systématiquement une EAccessViolation.

    La seule façon d'appeler le Create est comme ci c'était une méthode de classe soit dans ce cas TStringList.Create(); c'est une particularité du constructeur, cela va crée l'instance, allouée la mémoire nécessaire puis invoquer la méthode Create qui n'est qu'une sorte d'initialize au final.

    Je serais vous, je ferais une traque de tous les Create(), j'ai du mal à croire que cela n'ai jamais posé problème avant, je pense par exemple au TForm.
    Chercher la cause du problème de TStringList et TCheckListBox en dehors de la notion d'un CreateProcess, cela ne doit avoir aucun impact.

    Je ne parlerais pas d'utiliser des variables globales, normalement, on doit pouvoir sans passer à 99.9%, voir Pattern Singleton\Multiton aussi bien en D7 qu'en D11.
    Je dirais que la seule et unique variable globale publique (déclaré dans la section interface) doit être l'instance de la MainForm.
    Les autres variables globales doivent être privé (déclaré dans la section implementation) et encapsuler pour les accès et encore c'est pour une bonne raison, très rare en fait.

    L'utilisation de variable locale et de membre d'instance est toujours une meilleure approche.
    Sans rapport avec la notion de POO mais plutôt penser que moins une variable est exposée moins il y a de risque qu'un code la parasite.

  7. #7
    Membre régulier

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 540
    Points : 123
    Points
    123
    Par défaut Je peux pas.
    Regarde :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      for i := 0 to Nb_Procedures -1 do
        begin
          Ptr_Form.CheckListBox1.Items.Add(Lst_Noms_Proc.Strings[i]);
        end;
    Mon générateur de code (perso, pas du tout acheté) me génère des forms-types. Dont celle-là.
    Il y a un pointeur sur la Form générée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Var
        Form_Choix_Statistiques: TForm_Choix_Statistiques;
    Je pense que c'est cela qui gêne Delphi.
    Mais j'ai contourné le problème avec le for i.

    Ce n'est pas très élégant, mais c'est efficace.
    Et l'incidence sur le temps d'exécution est infime.

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 612
    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 612
    Points : 25 303
    Points
    25 303
    Par défaut
    Citation Envoyé par bvsud Voir le message
    Je pense que c'est cela qui gêne Delphi.
    Mais j'ai contourné le problème avec le for i.

    Ce n'est pas très élégant, mais c'est efficace.
    Et l'incidence sur le temps d'exécution est infime.
    Je dirais que tout cela n'a aucune rapport, Nb_Procedures doit forcément être compris entre 0 et Lst_Noms_Proc.Count (voire égale à ce dernier)

    Ce code doit fonctionner lorsque Nb_Procedures = Lst_Noms_Proc.Count
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Ptr_Form.CheckListBox1.Items.Assign(Lst_Noms_Proc);
    et ce Ptr_Form a de grande chance d'être faux si vous utiliser Create() de façon incorrecte même si je suppose que le DPR contient un tas de CreateForm au lieu de faire une gestion fine du cycle de vie des instances.

  9. #9
    Membre régulier

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 540
    Points : 123
    Points
    123
    Par défaut Bonjour, ShaireLeTrol
    Ouh... Je vais méditer ça.

    Et oui, le .DPR contient des TForm.Create.

    Je potasse cette réponse.

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/03/2008, 01h05
  2. [VB6] - Erreur mémoire avec une application multi feuille
    Par Aurazed dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 20/07/2007, 10h37
  3. Réponses: 1
    Dernier message: 16/05/2004, 17h56
  4. Réponses: 17
    Dernier message: 25/03/2003, 13h45
  5. Déterminer l'adresse d'une application en mémoire
    Par Gib dans le forum x86 32-bits / 64-bits
    Réponses: 9
    Dernier message: 11/06/2002, 14h27

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