TObjectList -> pointeur déréferencé

Résolu
Frenchy53 Messages postés 3 Date d'inscription mardi 22 août 2006 Statut Membre Dernière intervention 16 avril 2010 - 15 avril 2010 à 11:52
Frenchy53 Messages postés 3 Date d'inscription mardi 22 août 2006 Statut Membre Dernière intervention 16 avril 2010 - 16 avril 2010 à 13:58
Salut à tous,

Je viens vers vous car j'ai un problème de déréferencement de pointeur sur mes objets de ma TObjectList. Je m'explique :

Je dispose :

D'une classe mère TSurveillance instanciant deux TobjectList FListe_Definition : TObjectList;
FListe_Defauts : TObjectList;

 TSurveillance = class(TObject)
  private
    { Déclarations privées }
    Function TickToDate(const _Tick : cardinal) : String;

  protected
    { Déclarations protégées }
    FListe_Definition : TObjectList;
    FListe_Defauts : TObjectList;

    Procedure Set_Liste_Definition(_Liste_Definition : TObjectList); virtual;
    Procedure Set_Liste_Defauts(_Liste_Defauts : TObjectList); virtual;
    Procedure Gerer_Redondance (_Resultat_Surveillance : TResultat_Surveillance); virtual;

  public
    { Déclarations publiques }
    Constructor Create; overload; virtual;
    Constructor Create(_Liste_Definition : TObjectList); overload; virtual;
    Destructor Destroy; override;

    Property Liste_Definition : TObjectList read FListe_Definition write Set_Liste_Definition ;
    Property Liste_Defauts : TObjectList read FListe_Defauts write Set_Liste_Defauts ;

    // Fonctions d'accès à la liste des défauts
    Procedure Reset_Liste_Defauts ;

  end;


D'une classe descendante de TSurveillance s'intitulant TSurveillance_Arinc429

  TSurv_ARINC429 = class(TSurveillance)
  private
    { Déclarations privées }

  protected
    { Déclarations protégées }

  public
    { Déclarations publiques }
    Conforme : Boolean;

    Constructor Create; Override;
    Constructor Create(_List_Def_Arinc : TObjectList); Overload; Override;
    Destructor Destroy; Override;
...


Le soucis apparait dans chaque fonction utilisées de la classe TSurveillance_Arinc429. Par exemple celle-ci :

Function TSurv_ARINC429.Surv_Data_Max(_Label, _Data32b, _Borne_Sup: Cardinal) : Boolean;
Var
Index : Integer;
  Donnee : Cardinal;
  Resultat_Arinc429 : TResultat_Arinc429 ;

Begin

  Result := True ;

 // On parcourt le tableau de définitions de labels Arinc
  For Index := 0 To Liste_Definition.Count - 1 Do

  	// Si le label est trouvé et que l'on trouve la donnée à surveiller alors
If TDEF_ARINC429(Liste_Definition.Items[Index]).Label_Arinc = _Label Then
    Begin

    	// On récupère le LSB et le MSB de la donnée à évaluer nécessaire au masque
      Donnee := Get_Masked_Data(_Data32b,TDEF_ARINC429(Liste_Definition.Items[Index]).LSB_Data, TDEF_ARINC429(Liste_Definition.Items[Index]).MSB_Data);
      // On teste si la donnée est bien dans l'intervalle de tolérance
      If Donnee > _Borne_Sup Then
      Begin
        Result := False ;
      	Resultat_Arinc429 := TResultat_Arinc429.Create(TDEF_ARINC429(Liste_Definition.Items[Index]).Cle, False, TDEF_ARINC429(Liste_Definition.Items[Index]).Code_Defaut, Format(S_DEFAUT_BORNE_SUP_A429, [TDEF_ARINC429(Liste_Definition.Items[Index]).DataName, _Label, _Borne_Sup, Donnee]))
      End
      Else Resultat_Arinc429 := TResultat_Arinc429.Create(TDEF_ARINC429(Liste_Definition.Items[Index]).Cle, True, TDEF_ARINC429(Liste_Definition.Items[Index]).Code_Defaut, '');

      Gerer_Redondance(Resultat_Arinc429) ;

      Resultat_Arinc429.Free ;

End;

End; 


La fonction Gerer_Redondance permet de maintenir une liste d'objets de type TResultat_Arinc429. Resultat_Arinc429 est passé en paramètre d'entrée par copie. Cette fonction appartient à la classe générique TSurveillance.

Lorsque je fais Resultat_Arinc429.Free, il me détruit également l'objet passé par copie et présent dans la liste d'objets, or je souhaite qu'il soit gardé !
J'ai essayé pas mal de solutions, à savoir mettre OwnsObject à false sur la variable FListeDefauts mais rien n'y fait

J'espère avoir été assez clair. Si quelqu'un à une idée d'où vient mon probleme, j'attends avec impatience vos propositions...

Merci d'avance !

4 réponses

Frenchy53 Messages postés 3 Date d'inscription mardi 22 août 2006 Statut Membre Dernière intervention 16 avril 2010
16 avril 2010 à 13:58
C'est noté pour l'inherited

J'ai la solution à mon pb:
Mon objet Resultat_Arinc429 que je croyais passé par copie à la fonction Gerer_Redondance ne l'était pas. Du coup, au moment de faire Resultat_Arinc429.free, il me détruisait également l'objet de la liste...
La solution est soit de duppliquer l'objet dans la fonction Gerer_Redondance et libérer Resultat_Arinc429 dans la fonction appelante ou soit libérer l'objet Resultat_Arinc429 directement dans la fonction Gerer_Redondance.

Merci quand meme Foxi
3
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
15 avril 2010 à 13:09
faudrait tout le code pour corriger et tester.


________________________________________________________
besoin de câbles audio, vidèo, informatique pas cher ?
0
Frenchy53 Messages postés 3 Date d'inscription mardi 22 août 2006 Statut Membre Dernière intervention 16 avril 2010
15 avril 2010 à 13:42
Salut,

voici le code complet de la classe TSurveillance

unit Surveillance;

interface

uses
  Classes, Windows, SysUtils, ConvUtils, Dialogs, Math, idGlobal, Contnrs,
  Resultat_Surveillance;

type
{------------------------------------------------------------------------------}
{         								  CLASSE TSURVEILLANCE         									  	 }
{------------------------------------------------------------------------------}
{*------------------------------------------------------------------------------
  Classe de surveillance générique
-------------------------------------------------------------------------------}
 TSurveillance = class(TObject)
  private
    { Déclarations privées }
    Function TickToDate(const _Tick : cardinal) : String;

  protected
    { Déclarations protégées }
    FListe_Definition : TObjectList;
    FListe_Defauts : TObjectList;

    Procedure Set_Liste_Definition(_Liste_Definition : TObjectList); virtual;
    Procedure Set_Liste_Defauts(_Liste_Defauts : TObjectList); virtual;
    Procedure Gerer_Redondance (_Resultat_Surveillance : TResultat_Surveillance); virtual;

  public
    { Déclarations publiques }
    Constructor Create; overload; virtual;
    Constructor Create(_Liste_Definition : TObjectList); overload; virtual;
    Destructor Destroy; override;

    Property Liste_Definition : TObjectList read FListe_Definition write Set_Liste_Definition ;
    Property Liste_Defauts : TObjectList read FListe_Defauts write Set_Liste_Defauts ;

    // Fonctions d'accès à la liste des défauts
    Procedure Reset_Liste_Defauts ;

  end;


implementation

{ TSurveillance }
{*------------------------------------------------------------------------------
  Constructeur par défaut. Créé un objet de surveillance
-------------------------------------------------------------------------------}
Constructor TSurveillance.Create;
Begin

  FListe_Definition := TObjectList.Create ;
  FListe_Defauts := TObjectList.Create ;

End; //___________________________________________________________________Create

{*------------------------------------------------------------------------------
  Constructeur paramètré. Créé un objet de surveillance

  @param _Liste_Definition La liste des définitions
-------------------------------------------------------------------------------}
Constructor TSurveillance.Create(_Liste_Definition: TObjectList);
Begin

  FListe_Definition := TObjectList.Create;
  FListe_Definition.Assign(_Liste_Definition);
  FListe_Defauts := TObjectList.Create;

End; //___________________________________________________________________Create

{*------------------------------------------------------------------------------
  Destructeur

  Détruit la liste de définitions et de défauts
-------------------------------------------------------------------------------}
Destructor TSurveillance.Destroy;
Begin

  Inherited Destroy;

  FListe_Definition.Free;
  FListe_Defauts.Free ;

End; //__________________________________________________________________Destroy

{*------------------------------------------------------------------------------
  Procédure traitant la redondance des défauts constatés

  @param _Resultat_Surveillance Le résultat courant à traiter parmi la liste
-------------------------------------------------------------------------------}
Procedure TSurveillance.Gerer_Redondance(_Resultat_Surveillance: TResultat_Surveillance);
Var
  Index : Integer ;
  Index_Defaut : Integer ;
  Tps_Cumule : Cardinal ;

Begin

  Index_Defaut := -1 ;

  // On regarde si le défaut existe déja parmi la liste des défauts
  // On utilise Downto pour traiter en priorité les derniers défauts arrivés
  For Index := Liste_Defauts.Count - 1 Downto 0 Do
    If TResultat_Surveillance(Liste_Defauts.Items[Index]).Cle = _Resultat_Surveillance.Cle Then
    Begin
    Index_Defaut := Index ;
      Break ;
    End;

  // Le défaut exise déjà car il a été trouvé dans la liste
  If Index_Defaut >= 0 Then
  Begin

    Case TResultat_Surveillance(Liste_Defauts.Items[Index_Defaut]).Deb_Fin Of

      D : Begin

        // Si le résultat de la surveillance courante est false
        if Not _Resultat_Surveillance.Verdict Then
          // On incrémente le nombre d'apparitions
          TResultat_Surveillance(Liste_Defauts.Items[Index_Defaut]).Inc_Nb_Apparitions ;

        // Si le résultat de la surveillance courante est true
        If _Resultat_Surveillance.Verdict Then
        Begin

          // Calcul du temps d'appartion
          Tps_Cumule := GetTickCount - TResultat_Surveillance(Liste_Defauts.Items[Index_Defaut]).Tps_Deb ;

          // On regarde si le temps d'apparition du défaut est > à 100ms pour filtrer le "bagotement"
          // d'un défaut
          If Tps_Cumule < 100 Then
          Begin
            // On incrémente le nombre d'apparitions
            TResultat_Surveillance(Liste_Defauts.Items[Index_Defaut]).Inc_Nb_Apparitions ;
            // On réinitialise le temps d'apparition pour éviter de détecter un grand nombre de défauts en 200ms
            TResultat_Surveillance(Liste_Defauts.Items[Index_Defaut]).Tps_Deb := GetTickCount ;
          End
          Else
          Begin
            // Fin du défaut
            _Resultat_Surveillance.Deb_Fin := F ;
            // Application du temps cumulé du défaut
            _Resultat_Surveillance.Tps_Fin_Cumule := TickToDate(Tps_Cumule) ;
            // Ajout de la fin du défaut dans la liste
            Liste_Defauts.Add(_Resultat_Surveillance) ;
          End ;

        End ;

      End; // End D

      F : Begin

        // Si le résultat de la surveillance courante est false
        if Not _Resultat_Surveillance.Verdict Then
          // Réapparition du défaut et ajout à la liste des défauts
          Liste_Defauts.Add(_Resultat_Surveillance) ;

        // Si le résultat de la surveillance courante est true, le défaut n'est pas réapparu,
        // pas de traitement particulier

      End ; // End F

    End ; // End Case

  End
  Else
    // Le défaut n'éxistait pas auparavant, on l'ajoute à la liste des défauts
    // si le verdict de la surveillance est faux
    If Not _Resultat_Surveillance.Verdict Then Liste_Defauts.Add(_Resultat_Surveillance) ;

End; //_________________________________________________________Gerer_Redondance

{*------------------------------------------------------------------------------
  Procedure effacant tous les défauts constatés
-------------------------------------------------------------------------------}
Procedure TSurveillance.Reset_Liste_Defauts;
Begin

  If (FListe_Defauts <> nil) Then
    FListe_Defauts.Clear ;

End; //______________________________________________________Reset_Liste_Defauts

{*------------------------------------------------------------------------------
  Initialise la liste des défauts

  @param _Liste_Defauts La liste des défauts
-------------------------------------------------------------------------------}
Procedure TSurveillance.Set_Liste_Defauts(_Liste_Defauts: TObjectList);
Begin

  If (_Liste_Defauts <> Nil) Then
    FListe_Defauts.Assign(_Liste_Defauts);

End; //________________________________________________________Set_Liste_Defauts

{*------------------------------------------------------------------------------
  Initialise la liste des données à surveiller

  @param _Liste_Definition La liste de définition des données
-------------------------------------------------------------------------------}
Procedure TSurveillance.Set_Liste_Definition(_Liste_Definition: TObjectList);
Begin

  If (_Liste_Definition <> Nil) Then
    FListe_Definition.Assign(_Liste_Definition);

End; //_____________________________________________________Set_Liste_Definition

{*------------------------------------------------------------------------------
  Fonction qui convertit des millisecondes au format date

  @param _Tick Les millisecondes
-------------------------------------------------------------------------------}
Function TSurveillance.TickToDate(const _Tick: cardinal): String;
Var
H, N, S : Word;

Begin

S := (_Tick div 1000) mod 60;
  N := (_Tick div 60000) mod 60;
  H := (_Tick div 3600000);

  Result := format('%.2d:%.2d:%.2d',[H,N,S]);

End; //_______________________________________________________________TickToDate


Le code de la classe TSurveillance_Arinc429 avec une fonction générant le pb:

[code=pas]
unit Surv_ARINC429;

interface

uses
Classes, Windows, SysUtils, ConvUtils, Dialogs, Math, idGlobal, Contnrs,
Surveillance, Def_ARINC429, Resultat_Arinc429, Arinc429_Utils;

type
{------------------------------------------------------------------------------}
{ CLASSE TSURV_ARINC429 }
{------------------------------------------------------------------------------}
{*------------------------------------------------------------------------------
Classe de surveillance des données reçues sur le bus ARINC
Dérive de la classe TSurveillance
-------------------------------------------------------------------------------}
T32bitsSet = Set of 1..32 ;

TSurv_ARINC429 = class(TSurveillance)
private
{ Déclarations privées }

protected
{ Déclarations protégées }

public
{ Déclarations publiques }
Conforme : Boolean;

Constructor Create; Override;
Constructor Create(_List_Def_Arinc : TObjectList); Overload; Override;
Destructor Destroy; Override;

// Fonctions d'accès à la liste de définition
Procedure Set_Data_Arinc_Defined(_Label : Cardinal; _Yes_No : Boolean);
Procedure Set_All_Data_Arinc_Defined(_Yes_No : Boolean);
Procedure Define_Data_Arinc(_Label, _Data32b : Cardinal);
Procedure Redefine_Data_Arinc(_Label, _Data32b: Cardinal);
Function Get_Data(_Label : Cardinal) : Cardinal;
Function Get_Data_Phys(_Label: Cardinal): Single ;
Function Get_List_Labels : TStringList ;

// Fonctions de surveillances sur des données 32 bits
Function Surv_Absence_Arinc(_Num_Voie, _Nb_datamin, _Nb_datalues : Integer) : Boolean ;
Function Surv_Full_Data(_Label, _Data32b : Cardinal) : Boolean ;
Function Surv_Data_Partiel(_Label , _Data32b: Cardinal) : Boolean ;
Function Surv_Data_Intervalle(_Label, _Data32b, _Borne_Inf, _Borne_Sup : Cardinal) : Boolean ;
Function Surv_Data_Min(_Label, _Data32b, _Borne_Inf : Cardinal) : Boolean ;
Function Surv_Data_Max(_Label, _Data32b, _Borne_Sup : Cardinal) : Boolean ;
Function Surv_SDI(_Label, _Data32b : Cardinal) : Boolean ;
Function Surv_SSM(_Label, _Data32b : Cardinal) : Boolean ;
Function Surv_Parity(_Label, _Data32b : Cardinal) : Boolean ;
Function Surv_Bit_Value(_Label, _Data32b : Cardinal) : Boolean ;
Function Surv_All_Bit_Value(_Label, _Data32b : Cardinal) : Boolean ;
Function Surv_List_Bits_Value(_Label, _Data32b : Cardinal; _ListBits : T32bitsSet) : Boolean;

// Fonctions de surveillances sur données physiques à partir de données 32b
Function Surv_Data_Phys_Intervalle(_Label, _Data32b : Cardinal; _Borne_Inf, _Borne_Sup: Single) : Boolean ;
Function Surv_Data_Phys_Min(_Label, _Data32b : Cardinal; _Borne_Inf : Single) : Boolean ;
Function Surv_Data_Phys_Max(_Label, _Data32b : Cardinal; _Borne_Sup : Single) : Boolean ;
Function Surv_Var_Data_Phys(_Label, _Data32b : Cardinal; _Variation : Single) : Boolean ;

// Fonctions mathématiques
Procedure Reset_Stats(_Label : Cardinal) ;
Procedure Update_Stats(_Label, _Data32b : Cardinal);

end;

implementation

{*------------------------------------------------------------------------------
Constructeur par défaut. Créé un objet de surveillance Arinc429
-------------------------------------------------------------------------------}
Constructor TSurv_ARINC429.Create;
Begin

Inherited Create;
Conforme := True;

End; //___________________________________________________________________Create

{*------------------------------------------------------------------------------
Constructeur paramètré. Créé un objet de surveillance Arinc429

@param _List_Def_Arinc La liste des définitions de labels Arinc
-------------------------------------------------------------------------------}
Constructor TSurv_ARINC429.Create(_List_Def_Arinc : TObjectList);
Begin

Inherited Create(_List_Def_Arinc);
Conforme := True;

End; //___________________________________________________________________Create

{*------------------------------------------------------------------------------
Destructeur par défaut

Détruit la liste de définition de labels Arinc
-------------------------------------------------------------------------------}
Destructor TSurv_ARINC429.Destroy;
Begin

Inherited Destroy;

End; //__________________________________________________________________Destroy

{*------------------------------------------------------------------------------
Parcourt la liste de définition Arinc pour trouver le label recherché et
surveille que la donnée SDI soit identique à celle définie sur ce label

@param _Label Le label courant
@param _Data32b Le donnée courante reçue sur 32 bits
@return Le résultat du test
-------------------------------------------------------------------------------}
Function TSurv_ARINC429.Surv_SDI(_Label, _Data32b : Cardinal) : Boolean;
Var
Index : Integer;
Resultat_Arinc429 : TResultat_Arinc429 ;

Begin

Result := True ;

// On parcourt le tableau de définitions de labels Arinc
For Index := 0 To Liste_Definition.Count - 1 Do

If TDEF_ARINC429(Liste_Definition.Items[Index]).Label_Arinc = _Label Then
Begin

If TDEF_ARINC429(Liste_Definition.Items[Index]).SDI <> Extract_SDI_From_Data32b(_Data32b) Then
Begin
Result := False ;
Resultat_Arinc429 := TResultat_Arinc429.Create(TDEF_ARINC429(Liste_Definition.Items[Index]).Cle, False, TDEF_ARINC429(Liste_Definition.Items[Index]).Code_Defaut, Format(S_DEFAUT_SDI_A429, [_Label, TDEF_ARINC429(Liste_Definition.Items[Index]).SDI, Extract_SDI_From_Data32b(_Data32b)]))
End
Else Resultat_Arinc429 := TResultat_Arinc429.Create(TDEF_ARINC429(Liste_Definition.Items[Index]).Cle, True, TDEF_ARINC429(Liste_Definition.Items[Index]).Code_Defaut, '');

Gerer_Redondance(Resultat_Arinc429) ;

Resultat_Arinc429.Free ;

End;

End; //_________________________________________________________________Surv_SDI

....

[code=pas]

Merci d'avance
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
15 avril 2010 à 23:05
houlala ...

déjà le inherited du destructeur doit être à la fin du bloc, pas au début...

on verra aprés.

________________________________________________________
besoin de câbles audio, vidèo, informatique pas cher ?
0
Rejoignez-nous