Log in

View Full Version : Handles ... and how to explain ?



bg5
04-26-2012, 03:01 PM
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?

tls
04-26-2012, 03:15 PM
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
04-26-2012, 03:20 PM
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

tls
04-26-2012, 03:41 PM
I know this doesn't solve your problem, but why don't you just use GetBitmapAreaColors ?

masterBB
04-26-2012, 03:46 PM
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
04-26-2012, 04:06 PM
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
04-26-2012, 04:13 PM
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
04-26-2012, 04:27 PM
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).