AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Speicherleck oder nicht bzw. wer findet den Fehler?
Thema durchsuchen
Ansicht
Themen-Optionen

Speicherleck oder nicht bzw. wer findet den Fehler?

Ein Thema von phlux · begonnen am 15. Okt 2004 · letzter Beitrag vom 15. Okt 2004
Antwort Antwort
Benutzerbild von phlux
phlux

Registriert seit: 4. Nov 2002
Ort: Witten
1.335 Beiträge
 
Delphi 6 Personal
 
#1

Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:30
Servus
Hab schon laaange zeit nicht mehr gecodet deshalb passieren mir im Moment ziemlich dumme Fehler trotzdem hätt ich hier eine Frage mal zu klären.
Also ich habe ein Objekt
Delphi-Quellcode:
type
  TWasteItem = class(TComponent)
  private
    { Private-Deklarationen }
    // ...
  published
    { Published-Deklarationen }
    // ...
  end;
Dann erzeuge ich mit folgender Prozedur einen Dialog der zusätzlich eine property Waste: TWasteItem hat
Delphi-Quellcode:
procedure TMainForm.ShowItemDlg(Item: TWasteItem);
var
 ItemDlg: TItemDlg;

begin
  ItemDlg := TItemDlg.Create(Self);
  try
    If Item <> nil then
      ItemDlg.Waste := Item;
    ItemDlg.ShowModal;
  finally
    ItemDlg.Free;
  end;
end;
Jetzt will ich dem Dialog genau so ein Typ übergeben
Delphi-Quellcode:
procedure TMainForm.btnDBEditClick(Sender: TObject);
var
  wItem: TWasteItem;

begin
  wItem := TWasteItem.Create(Self);
  try
    ShowItemDlg(wItem);
  finally
// wItem.Free;
  end;
end;
Mein Problem ist jetzt wenn man wItem.Free nicht auskommentiert dann kommts zu ner Exception Lass ich das Free weg geht alles reibungslos nur dadurch entsteht dann doch ein Speicherleck weil ich den reservierten Speicher nicht mehr freigebe oder? Wäre nett wenn mir mal einer den richtigen Weg zeigen würde

mfg phluphie
Christian "phlux" Arndt
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:33
Kannst du den Code vom TItemDlg posten (Events wie FormCreate, Destroy, Close usw)
gibst du dort irgendwo Wast frei ?
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Benutzerbild von phlux
phlux

Registriert seit: 4. Nov 2002
Ort: Witten
1.335 Beiträge
 
Delphi 6 Personal
 
#3

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:37
Okay hier ist der Code von der DialogForm

Delphi-Quellcode:
unit frmItemDlg;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, JvExStdCtrls, JvEdit, Buttons, Mask,
  JvExMask, JvBaseEdits, JvValidateEdit, JvDatePickerEdit,
  JvCheckedMaskEdit, JvMaskEdit, JvToolEdit, WasteItem;

type
  TItemDlg = class(TForm)
    Panel1: TPanel;
    Bevel1: TBevel;
    Label1: TLabel;
    Label2: TLabel;
    Image1: TImage;
    GroupBox1: TGroupBox;
    Label5: TLabel;
    edTrans: TJvValidateEdit;
    edDisp: TJvValidateEdit;
    edOverall: TJvValidateEdit;
    Label6: TLabel;
    Label8: TLabel;
    Bevel2: TBevel;
    btnCancel: TButton;
    btnOK: TButton;
    GroupBox2: TGroupBox;
    Label3: TLabel;
    ItemList: TComboBox;
    DatePicker: TJvDatePickerEdit;
    Label7: TLabel;
    edWeight: TJvValidateEdit;
    Label4: TLabel;
    procedure btnCancelClick(Sender: TObject);
    procedure edOverallEnter(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ItemListKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure btnOKClick(Sender: TObject);
  private
    { Private-Deklarationen }
    fPath: String;
    fItems: TStringList;
// protected
    fWasteItem: TWasteItem;
  public
    { Public-Deklarationen }
    property Waste: TWasteItem read fWasteItem write fWasteItem;
  end;

var
  ItemDlg: TItemDlg;

implementation

{$R *.dfm}

procedure TItemDlg.btnCancelClick(Sender: TObject);
begin
  ModalResult := mrCancel;
end;

procedure TItemDlg.FormCreate(Sender: TObject);
begin
  fPath := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
  fItems := TStringList.Create;
  fWasteItem := TWasteItem.Create(Self);
  If FileExists(fPath + 'waste.itm') then
  begin
    ItemList.Items.LoadFromFile(fPath + 'waste.itm');
  end;
end;

procedure TItemDlg.FormDestroy(Sender: TObject);
begin
  ItemList.Items.SaveToFile(fPath + 'waste.itm');
  fWasteItem.Free;
  fItems.Free;
end;

procedure TItemDlg.btnOKClick(Sender: TObject);
begin
  fWasteItem.WasteType := ItemList.SelText;
  fWasteItem.Weight := edWeight.Value;
  fWasteItem.TransportCost := edTrans.Value;
  fWasteItem.DisposalCost := edDisp.Value;
  fWasteItem.Date := DatePicker.Date;
  ModalResult := mrOK;
end;

end.
Ich habe mir mal erlaubt die unrelevanten Teile (StringListe in eine Combobox laden&speichen) zu entfernen.
Christian "phlux" Arndt
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:40
Zitat von phlux:
Okay hier ist der Code von der DialogForm

Delphi-Quellcode:
unit frmItemDlg;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, JvExStdCtrls, JvEdit, Buttons, Mask,
  JvExMask, JvBaseEdits, JvValidateEdit, JvDatePickerEdit,
  JvCheckedMaskEdit, JvMaskEdit, JvToolEdit, WasteItem;

type
  TItemDlg = class(TForm)
    Panel1: TPanel;
    Bevel1: TBevel;
    Label1: TLabel;
    Label2: TLabel;
    Image1: TImage;
    GroupBox1: TGroupBox;
    Label5: TLabel;
    edTrans: TJvValidateEdit;
    edDisp: TJvValidateEdit;
    edOverall: TJvValidateEdit;
    Label6: TLabel;
    Label8: TLabel;
    Bevel2: TBevel;
    btnCancel: TButton;
    btnOK: TButton;
    GroupBox2: TGroupBox;
    Label3: TLabel;
    ItemList: TComboBox;
    DatePicker: TJvDatePickerEdit;
    Label7: TLabel;
    edWeight: TJvValidateEdit;
    Label4: TLabel;
    procedure btnCancelClick(Sender: TObject);
    procedure edOverallEnter(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ItemListKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure btnOKClick(Sender: TObject);
  private
    { Private-Deklarationen }
    fPath: String;
    fItems: TStringList;
// protected
    fWasteItem: TWasteItem;
  public
    { Public-Deklarationen }
    property Waste: TWasteItem read fWasteItem write fWasteItem;
  end;

var
  ItemDlg: TItemDlg;

implementation

{$R *.dfm}

procedure TItemDlg.btnCancelClick(Sender: TObject);
begin
  ModalResult := mrCancel;
end;

procedure TItemDlg.FormCreate(Sender: TObject);
begin
  fPath := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
  fItems := TStringList.Create;
  fWasteItem := TWasteItem.Create(Self); <================ Das Objekt wird nie freigegeben, das es überschrieben wird (mit deinem Wast)
  If FileExists(fPath + 'waste.itm') then
  begin
    ItemList.Items.LoadFromFile(fPath + 'waste.itm');
  end;
end;

procedure TItemDlg.FormDestroy(Sender: TObject);
begin
  ItemList.Items.SaveToFile(fPath + 'waste.itm');
  fWasteItem.Free; <=============== hier gibst du das übergebene Objekt frei !
  fItems.Free;
end;

procedure TItemDlg.btnOKClick(Sender: TObject);
begin
  fWasteItem.WasteType := ItemList.SelText;
  fWasteItem.Weight := edWeight.Value;
  fWasteItem.TransportCost := edTrans.Value;
  fWasteItem.DisposalCost := edDisp.Value;
  fWasteItem.Date := DatePicker.Date;
  ModalResult := mrOK;
end;

end.
Ich habe mir mal erlaubt die unrelevanten Teile (StringListe in eine Combobox laden&speichen) zu entfernen.
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#5

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:41
..... so wie ich das sehe, einfach die Create UND Destory weg, da du das Objekt ja von "aussen" befüllst !
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Benutzerbild von phlux
phlux

Registriert seit: 4. Nov 2002
Ort: Witten
1.335 Beiträge
 
Delphi 6 Personal
 
#6

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:43
Ahh alles klar dann muss ich einfach nur gucken im OnCreate und OnDestroy Event ob die Property Waste nil ist oder nicht und dementsprechend handeln, ich probier das mal so. Danke schon mal im vorraus

mfg phlux
Christian "phlux" Arndt
  Mit Zitat antworten Zitat
Keldorn

Registriert seit: 6. Mär 2003
Ort: Meißen
876 Beiträge
 
Delphi 10.1 Berlin Professional
 
#7

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:47
Delphi-Quellcode:
property Waste: TWasteItem read fWasteItem write fWasteItem;
...
procedure TItemDlg.FormCreate(Sender: TObject);
begin
  fPath := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
  fItems := TStringList.Create;
  fWasteItem := TWasteItem.Create(Self); <<<<---
  If FileExists(fPath + 'waste.itm') then
  begin
    ItemList.Items.LoadFromFile(fPath + 'waste.itm');
  end;
end;
...
procedure TItemDlg.FormDestroy(Sender: TObject);
begin
  ItemList.Items.SaveToFile(fPath + 'waste.itm');
  fWasteItem.Free; <<<---
  fItems.Free;
end;

...
procedure TMainForm.btnDBEditClick(Sender: TObject);
var
  wItem: TWasteItem;

begin
  wItem := TWasteItem.Create(Self);
  try
    ShowItemDlg(wItem);
  finally
// wItem.Free;
  end;
end;
So kannst du das nicht machen. Du erzeugst in deiner Form ein Wasteitem. mit
ItemDlg.Waste := Item; kopierts du nichts sondern "biegst" den Zeiger um. Fwasteitem zeigt jetzt auf das übergebene Item. Das ursprünglich erstellte fwasteitem ist dein Speicherleck, da du das nicht wieder freigeben kannst. Da du im destructor der Form fwasteitem freigibst, Fwasteitem und item aber durch die := -Zuweisung das gleiche objekt ist, siehts du eine exception beim erneuten Aufruf von free.

Keine Ahnung, für was du das brauchst, wenn es häufig vorkomt, das du ein item übergeben mußt:
property Waste: TWasteItem read fWasteItem write fWasteItem; verwende statt write write fwasteitem ein set-methode und verwende dort assign statt :=. Wenn du über eine >pro Version verfügst, gugg dir mal den Quelltext von einer Listbox an, und schau dir an, wie borland mit den Lines-eigenschaften umgeht.

Mfg Frank

Lükes Grundlage der Programmierung:
Es wird nicht funktionieren
(Murphy)
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:47
naja, im OnCreate wirds immer nil sein, da sie ja zu dieser zeit noch nicht initialisiert wurde (von deiner ItemDlg.Waste := Item
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Benutzerbild von phlux
phlux

Registriert seit: 4. Nov 2002
Ort: Witten
1.335 Beiträge
 
Delphi 6 Personal
 
#9

Re: Speicherleck oder nicht bzw. wer findet den Fehler?

  Alt 15. Okt 2004, 18:47
Hab es jetzt so umgeändert:

Delphi-Quellcode:
procedure TMainForm.btnDBEditClick(Sender: TObject);
var
  wItem: TWasteItem;

begin
  wItem := TWasteItem.Create(Self);
  ShowItemDlg(wItem);
end;

procedure TItemDlg.FormCreate(Sender: TObject);
begin
  fPath := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));
  fItems := TStringList.Create;
  //fWasteItem wird nur noch erstellt wenn an Waste kein Objekt vom Typ
  //TWasteItem übergeben wird
  if Waste = nil then
    fWasteItem := TWasteItem.Create(Self);
  If FileExists(fPath + 'waste.itm') then
  begin
    ItemList.Items.LoadFromFile(fPath + 'waste.itm');
  end;
end;
Den OnDestroy Event hab ich unangetastet gelassen da man ja so oder so das WasteItem übergibt und es dann frei gibt, ich habs also - so wie ich es verstanden hab - doppelt freigegeben.

mfg phlux

Edit: Stimmt, pack ich das ganze nach OnShow dann dürfte es stimmen
Christian "phlux" Arndt
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:54 Uhr.
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