I have been making a probram with big number of Bitmaps so I created an array for them. This makes it easy to shorten procedures with loops. But it also seems to give errors while Freeing the data. I tracked the problem and made it as easy to understand as possible, with this small sample:
...
private
{ Private declarations }
a: Array[0..3] of TBitmap;
b: TBitmap;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
a[1]:= TBitmap.Create;
b:= TBitmap.Create;
b.LoadFromFile('C:Test1.bmp');
a[1].LoadFromFile('C:Test2.bmp');
a[2]:= TBitmap.Create;
a[2]:= b;
a[3]:= TBitmap.Create;
a[3]:= b;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
a[1].Free;
a[2].Free;
a[3].Free;
b.Free;
a[1]:= nil;
a[2]:= nil;
a[3]:=nil;
b:= nil;
end;
...
If the bitmaps cannot be loaded, there is no error while freeing, otherwise the program will throw 'Access violation' error. Does anyone have any clues about this? I don't see any good reason, why this wouldn't work. It compiles nice, and free-command should usually never give errors.
Comments
:
: ...
: private
: { Private declarations }
: a: Array[0..3] of TBitmap;
: b: TBitmap;
: public
: { Public declarations }
: end;
:
: var
: Form1: TForm1;
:
: implementation
:
: {$R *.DFM}
:
: procedure TForm1.FormCreate(Sender: TObject);
: begin
: a[1]:= TBitmap.Create;
: b:= TBitmap.Create;
: b.LoadFromFile('C:Test1.bmp');
: a[1].LoadFromFile('C:Test2.bmp');
: a[2]:= TBitmap.Create;
: a[2]:= b;
: a[3]:= TBitmap.Create;
: a[3]:= b;
: end;
:
: procedure TForm1.FormDestroy(Sender: TObject);
: begin
: a[1].Free;
: a[2].Free;
: a[3].Free;
: b.Free;
: a[1]:= nil;
: a[2]:= nil;
: a[3]:=nil;
: b:= nil;
: end;
:
: ...
: If the bitmaps cannot be loaded, there is no error while freeing, otherwise the program will throw 'Access violation' error. Does anyone have any clues about this? I don't see any good reason, why this wouldn't work. It compiles nice, and free-command should usually never give errors.
:
The statements
[code]
a[2] := b;
a[3] := b;
[/code]
cause a[2] and a[3] to reference the same bitmap B. In this case if you Free a[2], you are also freeing a[3] and b. This will not cause any errors, since Free also works for not-created objects, but any other method will cause an access-violation.
The solution is quite simple: remove the b bitmap, and load the image into a[2] as you did for a[1]. Then use Assign() to copy the the bitmap from a[2] to a[3]. Do not use the default ":="-symbol, since that only copies the pointer, which points to the object itself.
: The statements
: [code]
: a[2] := b;
: a[3] := b;
: [/code]
: cause a[2] and a[3] to reference the same bitmap B. In this case if you Free a[2], you are also freeing a[3] and b. This will not cause any errors, since Free also works for not-created objects, but any other method will cause an access-violation.
: The solution is quite simple: remove the b bitmap, and load the image into a[2] as you did for a[1]. Then use Assign() to copy the the bitmap from a[2] to a[3]. Do not use the default ":="-symbol, since that only copies the pointer, which points to the object itself.
---
I thought it would copy the bitmap, not only the pointer. Wonder if I have made some bad mistakes.. Well many thanks for you, I see now what I was making wrong. Now I can finally continue my work.