Discussion: Fonctionnement du système de hash TFPGMap [Free Pascal]

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2009
    Messages : 18
    Points : 11
    Points
    11

    Par défaut Fonctionnement du système de hash TFPGMap

    Bonjour à tous,

    Je reviens vers vous car j'ai de nouveau un souci pour comprendre le fonctionnement et le comportement du langage.

    J'essaie juste de structurer un dictionnaire de HASH. Cela faisait des erreurs en mémoire.

    Alors, j'ai pris un exemple tout bête... Un dictionnaire de chaine de caractère...


    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
    {$mode objfpc}{$H+}
     
    uses sysutils,fgl ; 
     
    TYPE
     
    	HASHMAP_DeTest = specialize TFPGMap<string,String>;
     
    procedure TestMAP;  
     
    Var DICT_Test : HASHMAP_DeTest;
     
    begin  
     
    	DICT_Test := DICT_Test.Create;
    	//DICT_Test.Sorted = True; // Impossible de faire ce genre de chose
      //DICT_Test.add('Clef','Valeur');
      DICT_Test['Test'] := 'coucou';
     
     
    end;  
     
    begin  
      TestMAP;  
    end.
    Sous FP en compilant, impossible de trouver "crt" ... (je l'ai enlevé depuis)
    A la compilation avec FPC pas de problème ...

    Mais à l'execution ...

    31 lines compiled, 0.4 sec
    1 warning(s) issued
    An unhandled exception occurred at $000000000044DE11:
    EAccessViolation: Access violation
    $000000000044DE11
    $0000000000400259
    $0000000000400A1E

    J'ai pas dû faire comme il faut certainement, mais j'ai du mal a voir.

    Merci d'avance pour l'aide que vous pourrez m'apporter sur le sujet.

    Cordialement
    MAD

  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 081
    Points
    9 081

    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DICT_Test := HASHMAP_DeTest.Create;

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2009
    Messages : 18
    Points : 11
    Points
    11

    Par défaut

    Bonjour Andnotor,

    En effet, après avoir relu je me suis aperçu de ça.

    Je pensais quand faisant la déclaration dans VAR l'instanciation était effectuée.

    Pensant que c'était un langage objet, je croyais qu'il reservait la mémoire et copiait le code dedans.

    Erreur !
    Il faut donc reprendre la classe pour instancier l'objet déclaré...

    Merci en tout cas pour la réponse.

    Cordialement
    MAD

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    octobre 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2009
    Messages : 18
    Points : 11
    Points
    11

    Par défaut

    Voilà pour ceux qui serait dans mon cas, voici le corigé de l'exercice ...

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    {$mode objfpc}{$H+}
    {$R+}
     
    Program coucou;
     
     
    uses fgl; 
     
    TYPE
     
    	HASHMAP_DeTest = specialize TFPGMap<string, string>;
     
     
    Var DICT_Test : HASHMAP_DeTest;
    Var NBElements : integer;
    Var ind_NBElements : integer;
     
     
    begin  
     
    	//Il faut absolument instancier avec la classe et non avec le futur objet
    	DICT_Test := HASHMAP_DeTest.Create;
      	DICT_Test.add('Clef','Valeur');
    	DICT_Test['Clef2'] := 'Valeur2';
     
    	//On compte le nombre d'élément pour préparer la boucle. 
    	NBElements := DICT_Test.Count;
     
    	Writeln('Nombres d''éléments : ',NBElements);
     
    	//Lancement de la boucle de parcours	
    	For ind_NBElements := 0 to NBElements - 1 do
    	begin
    		//On affiche Ligne par ligne, la clef et la valeur
    		writeln(DICT_Test.Keys[ind_NBElements] + '=' + DICT_Test.Data[ind_NBElements]);		
        end;
     
        //Supprime une ligne
        DICT_Test.Remove('Clef');
     
        //Libère la mémoire 
        DICT_Test.Free;
    end.

  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 081
    Points
    9 081

    Par défaut

    Citation Envoyé par madndf Voir le message
    Je pensais quand faisant la déclaration dans VAR l'instanciation était effectuée.
    Non, tu ne fais que déclarer une variable pointeur typé.
    Et si des arguments sont nécessaires à la construction, comment ceux-ci pourraient-ils être déterminés automatiquement ?

    Citation Envoyé par madndf Voir le message
    Pensant que c'était un langage objet, je croyais qu'il reservait la mémoire et copiait le code dedans.
    Le code est là, c'est celui que tu as écrit, il n'y a aucune copie. A l'instanciation de l'objet, c'est la mémoire nécessaire à ses propriétés qui est allouée.
    Et c'est justement parce que c'est de l'objet qu'on ne peut pas savoir à coup sûr quel sera le type réel (contrairement à un record). Cela peut être le type déclaré comme un type dérivé (polymorphisme).

    Citation Envoyé par madndf Voir le message
    Il faut donc reprendre la classe pour instancier l'objet déclaré...
    Le type déclaré ou un type dérivé

    Mais ensuite il est tout à fait possible d'appeler le constructeur sur l'objet instancié (perso je ne le fait jamais). Il sera traité comme une simple méthode et retournera le même pointeur.

    Ceci est valide (mais pas forcément très compréhensible) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      DICT_Test : HASHMAP_DeTest;
     
    DICT_Test := HASHMAP_DeTest.Create;
    DICT_Test := DICT_Test.Create;

  6. #6
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Traqueur de tritons et autres bestioles
    Inscrit en
    mars 2002
    Messages
    1 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Traqueur de tritons et autres bestioles

    Informations forums :
    Inscription : mars 2002
    Messages : 1 489
    Points : 3 619
    Points
    3 619

    Par défaut

    Salut

    Citation Envoyé par madndf Voir le message
    Bonjour Andnotor,

    Je pensais quand faisant la déclaration dans VAR l'instanciation était effectuée.

    Pensant que c'était un langage objet, je croyais qu'il reservait la mémoire et copiait le code dedans.
    En quoi le fait d'être un langage objet oblige à cela ?

    Le Pascal Objet instancie ses objets sur le tas et cela depuis Delphi, jamais sur la pile comme peut le faire C++, c'est la continuité des allocations d'enregistrement sur le tas des Turbo Pascal.

    Une variable de type objet est une référence. Dans ce cadre, l'instanciation "automatique" rend poserait sans doute plus de problèmes car en déclarant une variable, on cherche peut-être à désigner un objet existant déjà référencé, il suffit de penser au passage d'un objet comme paramètre d'une routine. Si l'instanciation automatique existait, il faudrait désallouer après coup les objets crées pour se servir de leur identificateur comme nouvelle référence sur un objet existant. Ce qui serait passablement inefficace. On spécifie explicitement l'allocation.

    Quoiqu'il arrive, les instanciations d'objet en Pascal sont explicites (mêmes si elles sont parfois dissimulées), c'est en parfait accord avec la philosophie du Pascal "historique".

    Cdlt

    M E N S . A G I T A T . M O L E M
    Debian 8.x 64bit, Lazarus 1.6 (FPC 3.0), Python 3

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

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

Discussions similaires

  1. fonction dossiers système winsows 7
    Par hacbao dans le forum Windows 7
    Réponses: 2
    Dernier message: 19/12/2013, 14h56
  2. Lien fonctions C système et commandes shell
    Par DSGSLA dans le forum Linux
    Réponses: 1
    Dernier message: 01/09/2011, 18h54
  3. S-fonctions et système dynamique
    Par Hockenberhy dans le forum Simulink
    Réponses: 0
    Dernier message: 23/12/2009, 00h04
  4. Réponses: 8
    Dernier message: 04/08/2008, 12h19
  5. Réponses: 10
    Dernier message: 16/04/2007, 18h45

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