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/)
-   -   Zugriffsverletzung beim Freigeben von Objekten (https://www.delphipraxis.net/195322-zugriffsverletzung-beim-freigeben-von-objekten.html)

stifflersmom 20. Feb 2018 08:33

Zugriffsverletzung beim Freigeben von Objekten
 
Moin,
ich seh hier gerade meinen Fehler nicht, vielleicht schubst mich mal jemand in die richtige Richtung.

Ich fülle eine ComboBox mit einem erstellten Objekt und addObject. Das und der Zugriff darauf funktionieren, so weit ich das sehe, einwandfrei.
Aber in meiner Routine zum Freigeben des Speichers beim Schließen des Formulars knallts... aber warum?

Das Objekt:
Code:
type
  TGenericArticleModule = class
  private
    fCaption: string;
    fBg_Nr: Integer;
    property caption: string read fCaption;
    property Bg_nr: Integer read fBg_Nr;
    constructor Create(const caption: string; const bg_nr: Integer);
  end;
Das Hinzufügen zur Combobox:
Code:
procedure TfGenericArticle.GetModules;
var
  gaModule: TGenericArticleModule;
  sAssemblyGroup: string;
  iBg_nr: Integer;
begin
  if q_Work.Active then
    q_work.Close;
  q_work.SQL.Text := sSql_GenericArticleModule;
  q_work.Open;
  while not q_work.Eof do
    begin
      sAssemblyGroup := q_work.FieldByName('assembly_group_description').AsString;
      iBg_nr := q_work.fieldByname('bg_nr').AsInteger;
      gaModule := TGenericArticleModule.Create(sAssemblyGroup, iBg_nr);
      cb_module.Items.AddObject(sAssemblyGroup, gaModule);
      q_work.Next;
    end;
  if q_work.Active then
    q_work.Free;
end;
Und hier die Routine zum Freigeben des Speichers, wird beim Close des Formulars aufgerufen:
Code:
procedure TfGenericArticle.FreeObjects(targetList: Tstrings);
var
  I: Integer;
begin
  for I := targetList.Count - 1 downto 0 do
    targetList.Objects[i].Free;
end;

procedure TfGenericArticle.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  FreeObjects(cb_module.Items); // Hier kommt die Zugriffsverletzung
end;
Für einen kleinen Tipp wär ich dankbar

jziersch 20. Feb 2018 08:39

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Hallo,

Dafür wäre der Event OnDestroy praktischer - OnCloseQuery ist eigentlich nur eine Voranfrage und kommt nochmal wenn CanClose false ist.

Ich würde auch noch targetList.Clear aufrufen damit nicht aus versehen die Objekte nochmal abgemeldet werden.

Grüsse,
Julian
.

stifflersmom 20. Feb 2018 09:03

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Das wars leider nicht.
Knallt immer nocht bei:
Code:
 for I := targetList.Count - 1 downto 0 do
    targetList.Objects[i].Free;

Ghostwalker 20. Feb 2018 09:08

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Am besten mal mit dem Debugger durchgehen und checken, ob nicht evtl. cb_module, cb_module.items oder eines
der Objekte selbst bereits freigegeben wurden.

Lemmy 20. Feb 2018 09:15

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Zitat:

Zitat von stifflersmom (Beitrag 1394218)
Das Hinzufügen zur Combobox:
Code:
procedure TfGenericArticle.GetModules;
var
  gaModule: TGenericArticleModule;
  sAssemblyGroup: string;
  iBg_nr: Integer;
begin
  if q_Work.Active then
    q_work.Close;
  q_work.SQL.Text := sSql_GenericArticleModule;
  q_work.Open;
  while not q_work.Eof do
    begin
      sAssemblyGroup := q_work.FieldByName('assembly_group_description').AsString;
      iBg_nr := q_work.fieldByname('bg_nr').AsInteger;
      gaModule := TGenericArticleModule.Create(sAssemblyGroup, iBg_nr);
      cb_module.Items.AddObject(sAssemblyGroup, gaModule);
      q_work.Next;
    end;
  if q_work.Active then
    q_work.Free;
end;

mal was ganz anders: Warum steht da am Ende q_work.Free? Wo wird die erstellt?

Zitat:

Zitat von stifflersmom (Beitrag 1394222)
Das wars leider nicht.
Knallt immer nocht bei:
Code:
 for I := targetList.Count - 1 downto 0 do
    targetList.Objects[i].Free;

wo genau? bei allen Objekten? nur beim ersten (targetList.Count - 1) nur beim letzten (0)?

stifflersmom 20. Feb 2018 09:22

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Das q_work.free war Quatsch, hatte ich auch schon gesehen, aber das ist nicht das Problem.

Un knallen tut es definitiv nicht beim ersten Objekt das freigegeben wird, eher so gegen/am Ende der Liste.
ich bin gerade am schauen, ghostwalker hatte auch schon den Tip zu schauen ob ich nicht schon vorher was von den Objekten "gefreet" habe.

stifflersmom 20. Feb 2018 09:27

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Habs jetzt gefunden und Ghostwalker hatte Recht:
Beim Change der combobox hatte ich eine Variable vom typ TGenericArticleModule deklariert und versehentlich freigegeben.
Hatte aber auch nicht gedacht, dass ich mit der lokalen Variable ein Objekt der Liste in der comboBox rausschmeißen kann.

Nun mach ich es so und alles ist gut:
Code:
procedure TfGenericArticle.cb_moduleChange(Sender: TObject);
var
  sAssemblyGroup:String;
  iBg_Nr:Integer;
begin
  if cb_module.ItemIndex > -1 then
    begin
      sAssemblyGroup :=(cb_module.Items.Objects[cb_module.ItemIndex] as TGenericArticleModule).fCaption;
      iBg_Nr :=(cb_module.Items.Objects[cb_module.ItemIndex] as TGenericArticleModule).fBg_Nr;
      pn_filter.Caption := format('module: %s, BG_NR: %d', [sAssemblyGroup, iBg_Nr]);
    end;
end;
Danke auf jeden Fall!

himitsu 20. Feb 2018 10:08

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Delphi-Quellcode:
procedure TfGenericArticle.FreeObjects(targetList: Tstrings);
var
  I: Integer;
begin
  for I := targetList.Count - 1 downto 0 do
    targetList.Objects[i].Free;
  targetList.Clear; ///////////////
end;
Was passiert wohl, wenn das öfters ausgeführt wird?
Und stört es niemanden, wenn jemand das Schließen abbricht, die Form offen lässt, aber dennoch alles weg ist?

Warum keine ObjectList oder ein Dictionary, welche die Objekte selbstständig freigeben, wenn man das Item löscht?

freimatz 22. Feb 2018 08:49

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Das fragte ich mich gerade auch.
Zitat:

Zitat von stifflersmom (Beitrag 1394228)
Nun mach ich es so und alles ist gut

Eben nicht. Das ist unsauberer uncleaner code. Sowas ist fehleranfällig.
Generell sollte man Objects nie verwenden.

Lemmy 22. Feb 2018 09:15

AW: Zugriffsverletzung beim Freigeben von Objekten
 
Zitat:

Zitat von freimatz (Beitrag 1394401)
.
Generell sollte man Objects nie verwenden.

kannst Du das etwas näher erläutern?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:14 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