Forum > GTK

[solved] Unreleased DCs and unreleased GDIObjects - TImage memory leaks

<< < (2/4) > >>

andyH:
Thanks for that, I'll try both and see if I can whittle down the number of complaints from GTK. Particularly like the FormAbout:=nil;

howardpc:

--- Quote from: andyH on June 09, 2019, 06:15:57 pm ---I don't really understand .create(TheOwner : TComponent) and so far have been using self or nil where self doesn't work. Nor have I found anything useful on the web to improve my understanding.

--- End quote ---
The concept of ownership is introduced in the declaration of TComponent which provides a public Owner property of type TComponent. A TComponent instance specified as Owner to other components implements a mechanism to ensure that all its owned components are freed before it is itself freed.

All components (that is all TComponent descendants) thus inherit an automatic freeing mechanism not available to non-component classes such as streams, stringlists etc. which lack any kind of ownership mechanism.

Provided you supply a non-nil Owner in the constructor when you instantiate your TComponent descendant you can then forget about manually freeing it. Its Owner will do that for you.

Of course this only works successfully if the Owner you specify has a longer life span than the to-be-automatically-freed component. So the Owner is usually a form, or a datamodule or the Application instance, which in most typical programs will outlive the GUI controls you want automatically freed.

You can ignore this automatic freeing mechanism by passing Nil as the Owner for a newly constructed component. That means you as programmer are taking full responsibility for freeing the component. If you forget to Free it, you will have a leak. The only "owner" of such components is you, the programmer, and if you forget what you own, you are in for trouble.

andyH:
Thank you for that, my understanding improves by increments, just wish there was a resource somewhere that wrote all this down  :(

andyH:
Now I'm confused, I've removed all references to self or nil in all objects, they are now owned by either the mainform or a child of mainform, but am still getting the gtk errors on termination.

I've tracked the problem down to a confirmation form I put up to confirm the user's selections prior to doing the next action (a backup) - bypassing this form = no errors on exit.
The form is invoked from a file save dialog (to get the backup file name):

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---       if SaveDialog.Execute then          begin            BackFileName:= SaveDialog.Filename;            SaveDialog.Free;            ConfirmForm:= Tconfform.create(MainFm);            //set up labels. populate list boxes in the form            ...            ConfirmForm.Show;          endThere are two buttons on the confirm form, cancel and OK, the OK button onclick is:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure Tconfform.OkBtnCK(Sender : TObject);begin  writeln('Confirm - OK button clicked');  BkBackup;end;
And the first lines of BkBackup are (I don't know if you need both free and close, but I've tried all permutations):

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---begin  ConfirmForm.close;  ConfirmForm.free;  StartTime:= Time; //start time for partclone backup  ProgressFm:=TProgressFm.Create(MainFm.PageCtrl.Page[0]);  ProgressFm.Show;  and so on... I've also added an assign statement to the quit button on the mainform to exit the application:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---begin  if Assigned(ConfirmForm) then ConfirmForm.Free;  application.Terminate;end; Other than removing all reference to ConfirmForm and bypassing it, everything I've tried still throws up the GTK errors in my original post  :(

devEric69:
I advise you to code like this:

1°) you must drop a button "&OK" on your TConfirmForm, and set its ModalResult=mrOK.

2°) in your main form, you code:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  frmConfirmForm: TConfirmForm;begin  frmConfirmForm:= TConfirmForm.Create(Self);  try    frmConfirmForm.showmodal;    //you can test frmConfirmForm.modalResult ie which frmConfirmForm's btn has been clicked  finally    FreeAndNil(frmConfirmForm);  end;
3°) and in your callee modal dialog-box-form, you code this events:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TConfirmForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);begin  CloseAction:= caFree;end; procedure TConfirmForm.FormCloseQuery(Sender: TObject; var CanClose: TCloseAction);begin  CanClose:= True; //or a more complicated testend;
That way, you can be serene about possible memory leaks.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version