![]() |
Speicherleck oder nicht bzw. wer findet den Fehler?
Servus :hi:
Hab schon laaange zeit nicht mehr gecodet deshalb passieren mir im Moment ziemlich dumme Fehler :roll: trotzdem hätt ich hier eine Frage mal zu klären. :arrow: Also ich habe ein Objekt
Delphi-Quellcode:
:arrow: Dann erzeuge ich mit folgender Prozedur einen Dialog der zusätzlich eine property Waste: TWasteItem hat
type
TWasteItem = class(TComponent) private { Private-Deklarationen } // ... published { Published-Deklarationen } // ... end;
Delphi-Quellcode:
:arrow: Jetzt will ich dem Dialog genau so ein Typ übergeben
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;
Delphi-Quellcode:
Mein Problem ist jetzt wenn man wItem.Free nicht auskommentiert dann kommts zu ner Exception :x 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 ;)
procedure TMainForm.btnDBEditClick(Sender: TObject);
var wItem: TWasteItem; begin wItem := TWasteItem.Create(Self); try ShowItemDlg(wItem); finally // wItem.Free; end; end; mfg phluphie :hi: |
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
Kannst du den Code vom TItemDlg posten (Events wie FormCreate, Destroy, Close usw)
gibst du dort irgendwo Wast frei ? |
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
Okay hier ist der Code von der DialogForm ;)
Delphi-Quellcode:
Ich habe mir mal erlaubt die unrelevanten Teile (StringListe in eine Combobox laden&speichen) zu entfernen.
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. |
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
Zitat:
|
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
..... so wie ich das sehe, einfach die Create UND Destory weg, da du das Objekt ja von "aussen" befüllst !
|
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
Ahh :shock: 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 :hi: |
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
Delphi-Quellcode:
So kannst du das nicht machen. Du erzeugst in deiner Form ein Wasteitem. mit
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;
Delphi-Quellcode:
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.
ItemDlg.Waste := Item;
Keine Ahnung, für was du das brauchst, wenn es häufig vorkomt, das du ein item übergeben mußt:
Delphi-Quellcode:
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.
property Waste: TWasteItem read fWasteItem write fWasteItem;
Mfg Frank |
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
naja, im OnCreate wirds immer nil sein, da sie ja zu dieser zeit noch nicht initialisiert wurde (von deiner ItemDlg.Waste := Item;)
|
Re: Speicherleck oder nicht bzw. wer findet den Fehler?
Hab es jetzt so umgeändert:
Delphi-Quellcode:
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.
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; mfg phlux Edit: Stimmt, pack ich das ganze nach OnShow dann dürfte es stimmen :wall: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz