Re: [Lazarus] exception handling in constructor

2013-03-02 Thread Sven Barth

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

2013-03-02 Thread Howard Page-Clark

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

2013-03-02 Thread Hans-Peter Diettrich

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

2013-03-02 Thread Flávio Etrusco
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

2013-03-01 Thread Xiangrong Fang
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

2013-03-01 Thread Flávio Etrusco
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