Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Ungültige Zeigeroperation (https://www.delphipraxis.net/200683-ungueltige-zeigeroperation.html)

Trafel21 15. Mai 2019 10:58

Ungültige Zeigeroperation
 
Hallo zusammen,

ich bekomme eine Fehlermeldung 'Ungültige Zeigeroperation' beim Aufruf des Destructors nach dem schließen der Anwendung.


Delphi-Quellcode:
type
  TCallID = string;

  TCallInstance = class(TObject)
    CallID: String;
    CallFrom: String;
    CallTo: String;
    ChannelID: String;
    CallStart: TDateTime;
    CallEnd: TDateTime;
    CurrentEvent: TCallEvent;
  private
  public
  end;

  TCallInstanceDictionary = class(TObjectDictionary<TCallID,TCallInstance>)
  end;
  TCallInstanceDictionary = class(TObjectDictionary<TCallID,TCallInstance>)
  end;

  Tbc_AsteriskCallDictionaryDataModule = class(TDataModule)
    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
    function AddDictValue(ACallID: String): String;

  private
    { Private-Deklarationen }
    fCallInstanceDictionary: TCallInstanceDictionary;
  public
    { Public-Deklarationen }
  end;

var
  bc_AsteriskCallDictionaryDataModule: Tbc_AsteriskCallDictionaryDataModule;

implementation

procedure Tbc_AsteriskCallDictionaryDataModule.DataModuleCreate(Sender: TObject);
begin
  inherited;

  fCallInstanceDictionary := TCallInstanceDictionary.Create();
end;

procedure Tbc_AsteriskCallDictionaryDataModule.DataModuleDestroy(Sender: TObject);
begin
  inherited;
  fCallInstanceDictionary.Clear;
  fCallInstanceDictionary.free; // Hier Awnedungsfehlermeldung
end;
Ich vermute das ich der Create() funktion noch eigene Variablen von TCallID und TCallInstance übergeben muss aber
ansich funktioniert das Dictionary ohne Probleme.

TiGü 15. Mai 2019 11:02

AW: Ungültige Zeigeroperation
 
Wie ist es denn so?

Delphi-Quellcode:
procedure Tbc_AsteriskCallDictionaryDataModule.DataModuleDestroy(Sender: TObject);
begin
  fCallInstanceDictionary.Clear;
  fCallInstanceDictionary.free;

  inherited;
end;

DeddyH 15. Mai 2019 11:07

AW: Ungültige Zeigeroperation
 
Wieso eigentlich inherited, es handelt sich ja nicht um einen Destruktor?

TiGü 15. Mai 2019 11:13

AW: Ungültige Zeigeroperation
 
Stimmt! Ich sah nur "Destroy".
Das wird auch komplett ignoriert vom Compiler (keine blauen Punkte).

Uwe Raabe 15. Mai 2019 11:26

AW: Ungültige Zeigeroperation
 
Zitat:

Zitat von DeddyH (Beitrag 1432269)
Wieso eigentlich inherited, es handelt sich ja nicht um einen Destruktor?

In diesem Fall ist das wirklich obsolet, da die Klasse direkt von TDataModule abgeleitet wurde. Kommt allerdings Formvererbung ins Spiel, werden in einem Eventhandler bei inherited auch die in der DFM des Vorfahren verdrahteten Handler aufgerufen. Das ist zwar was völlig anderes als virtual/override, benutzt aber dasselbe Keyword.

haentschman 15. Mai 2019 11:40

AW: Ungültige Zeigeroperation
 
Delphi-Quellcode:
TCallInstanceDictionary = class(TObjectDictionary<TCallID,TCallInstance>)
end;
TCallInstanceDictionary = class(TObjectDictionary<TCallID,TCallInstance>)
end;
..ist das ein Copy/Paste Fehler? :gruebel:

Ownerships:
http://docwiki.embarcadero.com/Libra...tionary.Create

Das erkärt noch nicht den Fehler. Das müßte MemoryLeaks erzeugen. :gruebel:

Trafel21 15. Mai 2019 12:01

AW: Ungültige Zeigeroperation
 
Danke für die Antworten.

Zitat:

Zitat von Uwe Raabe (Beitrag 1432275)
Zitat:

Zitat von DeddyH (Beitrag 1432269)
Wieso eigentlich inherited, es handelt sich ja nicht um einen Destruktor?

In diesem Fall ist das wirklich obsolet, da die Klasse direkt von TDataModule abgeleitet wurde. Kommt allerdings Formvererbung ins Spiel, werden in einem Eventhandler bei inherited auch die in der DFM des Vorfahren verdrahteten Handler aufgerufen. Das ist zwar was völlig anderes als virtual/override, benutzt aber dasselbe Keyword.

Ich hab es entfernt. :) Danke für den Hinweis.

Zitat:

Zitat von haentschman (Beitrag 1432279)
Delphi-Quellcode:
TCallInstanceDictionary = class(TObjectDictionary<TCallID,TCallInstance>)
end;
TCallInstanceDictionary = class(TObjectDictionary<TCallID,TCallInstance>)
end;
..ist das ein Copy/Paste Fehler? :gruebel:

Ownerships:
http://docwiki.embarcadero.com/Libra...tionary.Create

Das erkärt noch nicht den Fehler. Das müßte MemoryLeaks erzeugen. :gruebel:

Ja, war ein Copy/Paste Fehler.

Ich bin noch einmal mit dem Debugger und F8 weiter rein.

Code:
//System.Classes

procedure TComponent.DestroyComponents;
var
  Instance: TComponent;
begin
  FreeAndNil(FSortedComponents);
  while FComponents <> nil do
  begin
    Instance := FComponents.Last;
    if (csFreeNotification in Instance.FComponentState)
      or (FComponentState * [csDesigning, csInline] = [csDesigning, csInline]) then
      RemoveComponent(Instance)
    else
      Remove(Instance);
    Instance.DisposeOf; //////// Hier wird der Fehler ausgelöst
  end;
end;

//SYSTEM.pas

procedure TObject.FreeInstance;
begin
  CleanupInstance;
  _FreeMem(Pointer(Self)); //////// hier wird angehalten, wenn ich die Option beim ausgelösten Fehler wähle
end;

haentschman 15. Mai 2019 13:19

AW: Ungültige Zeigeroperation
 
Hallöle...8-)

Der Fehler riecht danach, daß ein Objekt, was im Dictionary liegt, extern vom Dictionary mit Free freigeben wurde. Dann hat das Dictionary nur einen Pointer der nicht mehr existiert. Prüfe mal darauf. :wink:

Zeige mal wie du die Objekte erzeugst und in das Dictionary legst.

Trafel21 16. Mai 2019 05:25

AW: Ungültige Zeigeroperation
 
Zitat:

Zitat von haentschman (Beitrag 1432291)
Hallöle...8-)

Der Fehler riecht danach, daß ein Objekt, was im Dictionary liegt, extern vom Dictionary mit Free freigeben wurde. Dann hat das Dictionary nur einen Pointer der nicht mehr existiert. Prüfe mal darauf. :wink:

Zeige mal wie du die Objekte erzeugst und in das Dictionary legst.

Guten Morgen :-D das passiert so:


Code:
// neuen Anruf mit CallID anlegen
bc_AsteriskCallDictionaryDataModule.AddDictValue(GetCurrentCallID(StrBuffer));
Code:
procedure Tbc_AsteriskCallDictionaryDataModule.AddDictValue(ACallID: String);
var lCallInstance: TCallInstance;
begin

  if not fCallInstanceDictionary.TryGetValue(ACallID, lCallInstance) then
  begin
  lCallInstance := TCallInstance.Create;
  lCallInstance.CallID := ACallID;

  fCallInstanceDictionary.Add(ACallID, lCallInstance);
  end
end;
Wenn ich Werte innerhalb der CallInstance bearbeiten möchte ruf ich die trygetvalue von Dictionary auf

Bspw.:

Code:
function Tbc_AsteriskCallDictionaryDataModule.GetChannelID(ACallID: String): String;
var lCallInstance: TCallInstance;
begin
  if (fCallInstanceDictionary.TryGetValue(ACallID, lCallInstance)) then
  result := lCallInstance.ChannelID;
end;

procedure Tbc_AsteriskCallDictionaryDataModule.SetCallEnd(ACallID: String; AToday: TDateTime);
var lCallInstance: TCallInstance;
begin
  if(fCallInstanceDictionary.TryGetValue(ACallID, lCallInstance)) then
  begin
    lCallInstance.CallEnd := AToday;
  end;
end;

haentschman 16. Mai 2019 05:37

AW: Ungültige Zeigeroperation
 
Moin...8-)
Sieht unspektulär aus...:gruebel: Kein Free für eine TCallInstance?

Versuche mal das:
Delphi-Quellcode:
procedure Tbc_AsteriskCallDictionaryDataModule.DataModuleCreate(Sender: TObject);
begin
  inherited;

  fCallInstanceDictionary := TCallInstanceDictionary.Create([doOwnsValues]); // die Values werden von der Liste freigeben
end;

procedure Tbc_AsteriskCallDictionaryDataModule.DataModuleDestroy(Sender: TObject);
begin
  inherited;
//  fCallInstanceDictionary.Clear; // vor dem Free brauchst du das nicht
  fCallInstanceDictionary.Free;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:56 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz