[solved] TBitmap free or destroy lazarus / 39-Graphics ---------------------------------------------------------------------- dcelso · 2013-01-30 16:17 ¿Hello, anyone knows the difference bettween free a tbitmat with .free o .destroy? ---------------------------------------------------------------------- Blaazen · 2013-01-30 16:32 Press Alt+Up and you will see: Code: [Select]procedure TObject.Free;         begin            // the call via self avoids a warning            if self<>nil then              self.destroy;         end;               So you see that Free calls Destroy. And even better than "BMP.Free;" can be: Code: [Select]FreeThenNil(BMP); ---------------------------------------------------------------------- dcelso · 2013-01-30 16:37 , thanks. I'll remember from now. ---------------------------------------------------------------------- dcelso · 2013-01-30 16:42 Then, if I need do it in a loop (of minimum 1000 times), and I control well the non null access, is it better use .destroy to gain performance and do faster the application.? ---------------------------------------------------------------------- taazz · 2013-01-30 17:52 you should not create and destroy bitmaps in a loop you can clear and reuse them as needed it ill be faster mainly from avoiding to re create all the internal structures and memory allocation and re allocation etc. ---------------------------------------------------------------------- User137 · 2013-01-30 18:37 Quote from: Blaazen on January 30, 2013, 05:32:16 pmAnd even better than "BMP.Free;" can be: Code: [Select]FreeThenNil(BMP);I have seen this typo one or more times before. FreeAndNil(object) is correct form. ---------------------------------------------------------------------- Blaazen · 2013-01-30 18:44 It's not typo, they exist both. If you have enough time: http://www.mail- archive.com/lazarus@lists.lazarus.freepascal.org/msg19483.html There are maybe 100 mails but honestly, I did not fully catch the difference ---------------------------------------------------------------------- dcelso · 2013-01-31 17:16 I not find FreeThenNil fuction unit in lazarus 1.1 (daily). Only I found FreeAndNil on sysutilh.inc Is This function in another unit? ---------------------------------------------------------------------- User137 · 2013-01-31 18:12 It was in LCLProc unit, so it's not found in Delphi either. ---------------------------------------------------------------------- dcelso · 2013-02-01 07:53 , i saw it. Code: [Select]procedure FreeThenNil(var obj); begin   if Pointer(obj) <> nil then   begin     TObject(obj).Free;     Pointer(obj) := nil;   end; end;  procedure FreeAndNil(var obj);       var         temp: tobject;       begin         temp:=tobject(obj);         pointer(obj):=nil;         temp.free;  end; But I don't see the difference, both do the same for me. Anyone can explain me the real difference in a application, for example, like me, a loop. Thanks ---------------------------------------------------------------------- Ask · 2013-02-01 08:21 FreeAndNil will crash if object destructor accesses Self. FreeThenNil is not thread-safe, since there is a window for a race between destroying an object and clearing the reference. ---------------------------------------------------------------------- taazz · 2013-02-01 08:38 Quote from: Blaazen on January 30, 2013, 07:44:19 pmIt's not typo, they exist both. If you have enough time: http://www.mail- archive.com/lazarus@lists.lazarus.freepascal.org/msg19483.html There are maybe 100 mails but honestly, I did not fully catch the difference  for a small example of the differences on usage take a look at  http:/ /www.lazarus.freepascal.org/index.php/topic,19207.msg109134.html#msg10 9134 this should give you an idea about the problems that might raise. Let me also add at this point that using freeandnil makes extending components a bit easier avoiding some of the flow problems that might be introduced on a descendant component from, usually, a different developer, who might or might not have the time to properly analyze the underline code. Quote from: Ask on February 01, 2013, 09:21:24 amFreeAndNil will crash if object destructor accesses Self. I'd like some example of this, as far as I can understand freeandnil should set the variable holding the reference to the object to nil not the self "variable" of the object. If it does play havoc with the self "variable" then there is something wrong that needs investigation. ---------------------------------------------------------------------- howardpc · 2013-02-01 08:38 A destructor that accesses Self is poorly written, and normally ought to crash. So you are safer sticking to FreeAndNil (unless you really know what you are doing, or imagine you do). ---------------------------------------------------------------------- Ask · 2013-02-01 09:06 Quotefreeandnil should set the variable holding the reference to the object to nil not the self "variable" of the object.Yes, I wrote too hastily. I meant "if object destructor accesses Self indirectly". For example, consider TForm.Destroy which calls "OnDestroy" event handler, which might be written by another programmer and carelessly access "Form1.SomeProperty". (Actual TForm.Destroy does not work so simply, it is just an example). ---------------------------------------------------------------------- taazz · 2013-02-01 09:29 thank you for the clarification and I agree. Quote from: Ask on February 01, 2013, 10:06:10 amYes, I wrote too hastily. I meant "if object destructor accesses Self indirectly". For example, consider TForm.Destroy which calls "OnDestroy" event handler, which might be written by another programmer and carelessly access "Form1.SomeProperty". thank you for the clarification. Quote from: Ask on February 01, 2013, 10:06:10 am(Actual TForm.Destroy does not work so simply, it is just an example). It does not matter how complicated the logic behind the destruction process is the variable has been set to nil before the destructor is called so it should raise an exception. ---------------------------------------------------------------------- User137 · 2013-02-01 13:35 I made simple example, if i understood right: Code: [Select]type   { TTestClass }   TTestClass = class   public     sl: TStringList;     constructor Create;     destructor Destroy; override;   end;   { TForm1 }   TForm1 = class(TForm)     procedure FormCreate(Sender: TObject);     procedure FormDestroy(Sender: TObject);   private     test: TTestClass;   public   end; var   Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin   test:=TTestClass.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin   FreeAndNil(test); end; { TTestClass } constructor TTestClass.Create; begin   sl:=TStringList.Create; end; destructor TTestClass.Destroy; begin   form1.test.sl.Free; // Crashes (uncommented)   //sl.Free; // Works normally   //self.sl.Free; // Also works normally   inherited Destroy; end; ---------------------------------------------------------------------- taazz · 2013-02-01 13:55 Quote from: User137 on February 01, 2013, 02:35:38 pmI made simple example, if i understood right: An example of what? If this is directed to my request at Ask, then you have missed his point. here is what I understood. Code: [Select]type   { TForm1 }   TForm1 = class(TForm)     Button1 : TButton;     procedure FormDestroy(Sender: TObject);     procedure Button1Click(Sender: TObject);   end; var   Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormDestroy(Sender: TObject); begin   ShowMessage(Form1.Button1.Caption); end; procedure TForm1.Button1Click(Sender: TObject); begin   FreeAndNil(Form1); end; although the form and button are steel accessible and the showmessage will work as expected if you remove the "form1." when the event is raised the form1 variable is already nil so it will raise an exception. Of course that example violates so many coding prιnciples that its not something you should encounter ever. ---------------------------------------------------------------------- User137 · 2013-02-01 14:32 Isn't that exactly same thing... I just didn't go as far as to destroy form within its own methods, because that is way out of standard. So i just used a second class for it. ---------------------------------------------------------------------- taazz · 2013-02-01 14:46 no it would be the same thing if you accessed the Test private variable from the TestClass.destroy method. ---------------------------------------------------------------------- User137 · 2013-02-01 14:55 I did Code: [Select]destructor TTestClass.Destroy; begin   //form1.test.sl.Free; // Crashes ---------------------------------------------------------------------- taazz · 2013-02-01 15:07 sorry I'm used to ignore comment lines when speed reading, so I never show that line. In any case both examples violate coding principles its no something I expect to see and if I ever see such code in any library I would drop it immediately.