Re: [Lazarus] exception handling in constructor
On 02.03.2013 03:49, Xiangrong Fang wrote: Hi there, If my class constructor looks like this: constructor TMyClass.Create(fn: string); begin sl := TStringList.Create; try fs := TFileStream.Create(fn, fmOpenRead); except self.Destroy; end; end; No, this is a bad idea. If an exception occurs inside the constructor the destructor will be called automatically. I don't even want to think about what bad things could happen if you call Destroy inside the constructor... I create the objec like: MyInstance := TMyClass.Create('AnNonExistentFile'); An exception occured, I can ensure that: 1. there is no memory leak. There won't be a memory leak. 2. the MyInstance variable is assigned *nil*? If you want to ensure that MyInstance is Nil you need to do it like this: === code begin === try MyInstance := TMyClass.Create('AnNonExistentFile'); except MyInstance := Nil; end; === code end === Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] exception handling in constructor
On 02/03/13 10:51, Michael Van Canneyt wrote: This will definitely cause a memory leak, because the FPC code does not know that an exception occurred in the constructor (you catch it with Except), and hence will not call the destructor. Thanks for the correction and explanation. Howard -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] exception handling in constructor
Sven Barth schrieb: If you want to ensure that MyInstance is Nil you need to do it like this: === code begin === try MyInstance := TMyClass.Create('AnNonExistentFile'); except MyInstance := Nil; end; === code end === When an exception occurs in Create, the assignment will never take place. That's why MyInstance should be set to Nil *before* calling the constructor. This also applies to memory leak protection of multiple temporary objects: inst1 := nil; inst2 := nil; ... try inst1 := T1.Create; inst2 := T2.Create; ... finally inst1.Free; inst2.Free; ... end; The Free does no harm, even if the instances never were created, when the variables are nil'ed before the try block. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] exception handling in constructor
On Sat, Mar 2, 2013 at 7:51 AM, Michael Van Canneyt mich...@freepascal.org wrote: On Sat, 2 Mar 2013, Howard Page-Clark wrote: On 02/03/13 5:45, Flávio Etrusco wrote: On Fri, Mar 1, 2013 at 11:49 PM, Xiangrong Fang xrf...@gmail.com wrote: (...) Also, setting Self to nil is nonsense. If you do FreeAndNil(Self) instead, it will work. But I would seriously warn against doing this kind of thing. Wow, this is unexpected. I always thougth that by definition a constructor would never return nil - so Self was a by-value parameter, even inside a constructor. Is this by design? I never saw the point of allowing assign to Self,... -Flávio -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] exception handling in constructor
Hi there, If my class constructor looks like this: constructor TMyClass.Create(fn: string); begin sl := TStringList.Create; try fs := TFileStream.Create(fn, fmOpenRead); except self.Destroy; end; end; I create the objec like: MyInstance := TMyClass.Create('AnNonExistentFile'); An exception occured, I can ensure that: 1. there is no memory leak. 2. the MyInstance variable is assigned *nil*? Thanks -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] exception handling in constructor
On Fri, Mar 1, 2013 at 11:49 PM, Xiangrong Fang xrf...@gmail.com wrote: Hi there, If my class constructor looks like this: constructor TMyClass.Create(fn: string); begin sl := TStringList.Create; try fs := TFileStream.Create(fn, fmOpenRead); except self.Destroy; end; end; I create the objec like: MyInstance := TMyClass.Create('AnNonExistentFile'); An exception occured, I can ensure that: 1. there is no memory leak. I assume FPC behaves like Delphi, so there's no leak. Actually, you don't even need to explicitly call Destroy; when an exception occurs in a constructor the destructor is called automatically. 2. the MyInstance variable is assigned nil? No, it's not initialized. Thanks Regards, Flávio -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus