TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
-
davidnovo
- Newbie
- Posts: 15
- Joined: Mon Nov 30, 2009 12:00 am
Post
by davidnovo » Wed Dec 15, 2010 6:03 am
Hello,
In TeeCreateMetafile you create the bitmap and assign to the result on the first line. Then do a bunch of stuff, including setting the size of the bitmap. Problem is if there is an exception (lets say setting the size too big) you will always leak a bitmap because the result of the function is undefined and if there is an exception in teh method.
i.e.
Code: Select all
bmp:=nil;
try
bmp:=TeeCreateBitmap(someSize);
.. do some stuff with bitmap
finally
bmp.free
end
if there was an exception in TeeCreateBitmap (i.e. somesize was too large) it will jump to the finally, but bmp won't be assigned because the result of the function will be invalid and bmp will still be nil. You need to put a try except inside teeCreateBitmap to prevent a leak in this case.
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Thu Dec 16, 2010 2:22 pm
Hi David,
I'm not sure to understand it. I see no TeeCreateBitmap function with a single argument. I can see one without arguments and one with several (minimum a TColor and a TRect). See the signatures:
Code: Select all
Function TCustomTeePanel.TeeCreateBitmap:TBitmap;
Code: Select all
Function TCustomTeePanel.TeeCreateBitmap(ABackColor:TColor; Const Rect:TRect;
APixelFormat:{$IFNDEF CLX}Graphics.{$ENDIF}TPixelFormat=
{$IFDEF CLX}TeePixelFormat{$ELSE}pfDevice{$ENDIF};
ADpi:Integer=0):TBitmap;
With the first one you can do as follows:
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var tmp: TBitmap;
begin
Chart1.AddSeries(TLineSeries);
Chart1[0].FillSampleValues(10);
tmp:=Chart1.TeeCreateBitmap;
end;
Isn't it what you want?
-
davidnovo
- Newbie
- Posts: 15
- Joined: Mon Nov 30, 2009 12:00 am
Post
by davidnovo » Fri Dec 17, 2010 7:53 am
Hello Yeray....
I am talking about the one with several. I was working from memory so messed it up.
if you do
Code: Select all
try
tmp:=chart1.TeeCreateBitmap(clRed,Rect(0,0,100000,00000))
finally
tmp.Free
end;
you will not really free the bitmap. That is because TeeCreateBitmap will raise an exception and not return the bitmap it created. There is no way for me as a user to make sure I don't have a memory leak in the event that there is an exception in TeeCreateBitmap.
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Fri Dec 17, 2010 11:42 am
Hi David,
I guess you meant
100000 as Bottom parameter, where you wrote
00000.
What about this:
Code: Select all
uses Series, Types;
procedure TForm1.FormCreate(Sender: TObject);
begin
with Chart1.AddSeries(TPieSeries) do FillSampleValues();
end;
procedure TForm1.Button1Click(Sender: TObject);
var tmp: TBitmap;
tmpRect: TRect;
begin
tmp:=nil;
tmpRect:=Rect(0,0,100000,100000);
// tmpRect:=Rect(0,0,Chart1.Width,Chart1.Height);
try
try
tmp:=Chart1.TeeCreateBitmap(clRed,tmpRect);
tmp.SaveToFile('C:\tmp\test.bmp');
except
on E : EOutOfResources do
ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
end;
finally
if tmp <> nil then
tmp.Free;
end;
end;
-
davidnovo
- Newbie
- Posts: 15
- Joined: Mon Nov 30, 2009 12:00 am
Post
by davidnovo » Fri Dec 17, 2010 3:08 pm
Yes I did. But really any size that is too big will do it.
But that is just an example of an easy way to reproduce it. ANY Exception that happens to be raised inside TeeCreateBitmap will do this.
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Mon Dec 20, 2010 2:23 pm
Hi David,
I've added it to the wish list to be studied for inclusion in future releases (TV52015328).
In the meanwhile you could use the mentioned workaround.
-
davidnovo
- Newbie
- Posts: 15
- Joined: Mon Nov 30, 2009 12:00 am
Post
by davidnovo » Mon Dec 20, 2010 7:58 pm
Hello,
In your sample code, you check for tmp<>nil then call tmp.Free. The tmp<>nil check is not necessary. You can call .Free on a nil object.
Second, your workaround simply will not work. Just because tmp=nil does not mean the bitmap was not leaked.
our code is even simpler than your worklaround
rect:=some big rectc
tmp:=nil;
try
tmp:=chart1.TeeCreateBitmap(clNone,someBigRect)
finally
tmp.Free
end
and that will still generate a memory leak if there is an Exception in TeeCreateBitmp because a bitmap is created in TeeCreateBitmap and NOT passed back as the result. Since it is not passed back, there is nothing for me to free. There is no workaround that I can do that will result in non memory leak. You have to free the created bitmap in TeeCreateBitmap.
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Tue Dec 21, 2010 4:17 pm
Hi David,
Excuse me, I haven't understood well what you were trying to explain. I've clarified the explanation of the enhancement request.
I recommend you to be aware at this forum or subscribe to our
RSS news feed for new release announcements and what's implemented on them.