SRL Archive - Help

Handles ... and how to explain ?


bg5

2012-04-26 11:01:47

I think you should compile this code to understand my problem ,because it's quite complex ,and I can't describe it clear:P

program new;

Function BmpToTIA(Bitmap_Handle : integer): T2dIntegerArray;
Var
I, J ,w ,h : Integer;
B : TBitmap;
Begin
try
B := TBitmap.Create;
B.Handle := Bitmap_Handle;
w := B.Width;
writeln('inside function '+tostr(w));
h := B.Height;
SetLength(Result,w);
For I:= 0 to w-1 Do
SetLength(Result[I],h);
For I := 0 to w-1 Do
For J := 0 to h-1 Do
Result[I][J] := B.Canvas.Pixels[I, J];
B.Free; // this line is evil
except
writeln('Exeption in BmpToTIA');
end;
End;

var
f,ff : T2dIntegerArray;
bmp,bmp2,w,h ,a:integer;
M : Tmufasabitmap;
B_global : Tbitmap;
begin
GetClientDimensions(w,h);
bmp := bitmapfromclient(1,1,w-1,h-1);
M := GetMufasaBitmap(bmp);

B_global := M.ToTBitmap;
writeln('global :' +tostr(b_global.Width) +' handle: ' +tostr(B_global.Handle));

f := BmpToTIA(b_global.Handle );
writeln('global :' +tostr(b_global.Width) +' handle: ' +tostr(b_global.handle)+ ' - global object didn''t change ,but:');
ff := BmpToTIA(b_global.Handle );
writeln('It can''t be used by function any more!');
M.Free;
end.

Output:

global :149    handle: 855972512
inside function 149
global :149 handle: 855972512 - global object didn't change ,but:
inside function 0
It can't be used by function any more!

Basically what I have here:

First i made Tbitmap object with image of client inside (B_global). Then I put it's handle to function ,which do stuff with it (in this case converts bitmap to T2dintegerarray ,but it's not important).
Inside function I made new Tbitmap object (B) and assigned it to handle of global TBitmap. After all I add line B.Free; ,which should free local obcject and not affect global one.

But ,what is very weird ,this line (B.Free;) do something ,that if I sent global object to this function second time it can't use it (see output).

1. Anyone can explain this?

2. If I create local object inside a function and don't free it ,it will be free automatically when function executed or i will have memory leak?

mormonman

2012-04-26 11:15:10

Since you use the actual handle of the bitmap, it frees it from simba's memory. I suggest using something like CopyBitmap. You actually aren't created a new object, you are accessing the object memory differently. /not-entirely-sure

bg5

2012-04-26 11:20:24

From: mormonman
Since you use the actual handle of the bitmap, it frees it from simba's memory. I suggest using something like CopyBitmap. You actually aren't created a new object, you are accessing the object memory differently. /not-entirely-sure


But look at output , I wrote that debug to check ,if global object still exist …and it still exist:

global :149    handle: -771417308 // before function
inside function 149 // here is function
global :149 handle: -771417308 - global object didn't change ,but: // after function's object was freed ,global still exist

mormonman

2012-04-26 11:41:32

I know this doesn't solve your problem, but why don't you just use GetBitmapAreaColors ?

masterBB

2012-04-26 11:46:01

I also want to know this. Will think about it. Though you know everytime you call TBitmap.Create you create a new handle… This might be a bit of memory hogging.

bg5

2012-04-26 12:06:57

From: mormonman
I know this doesn't solve your problem, but why don't you just use GetBitmapAreaColors ?


Because I didn't know this :P Anyway this function is only example ,the problem might concern many other functions.

masterBB

2012-04-26 12:13:25

From: beginner5
Because I didn't know this :P Anyway this function is only example ,the problem might concern many other functions.


Just don't use handles. I don't understand it either. But you will create a memory leak if you remove the b.Free; Simba does frees all local variables automatically, but not handlers. A TBitmap var is basically a handler. A suggest to use either this:

Function BmpToTIA(Bitmap:Tbitmap): T2dIntegerArray;
Var
I, J ,w ,h : Integer;
Begin
w := Bitmap.Width;
writeln('inside function '+tostr(w));
h := Bitmap.Height;
SetLength(Result,w);
For I:= 0 to w-1 Do
SetLength(Result[I],h);
For I := 0 to w-1 Do
For J := 0 to h-1 Do
Result[I][J] := Bitmap.Canvas.Pixels[I, J];
End;

Or

GetBitmapAreaColors

bg5

2012-04-26 12:27:50

Hmm… But if you add line Bitmap.Free; you will see ,that global object was destroyed! So basically :
 Function BmpToTIA(Bitmap:Tbitmap): T2dIntegerArray;
=
Function BmpToTIA(var Bitmap:Tbitmap): T2dIntegerArray;
:P It's not good ,when you don't want to touch global object.

I didn't know this before too ,it looks like passing class object to functions is like passing pointer to this object ( like in java).