SRL Archive - Bugs

Two Memory leaks: in CombineTPA , in TPAFromCircle


bg5

2012-05-11 03:02:48

I was testing this little script ,when it was interrupted by very unexpected error:
Error: Exception: Out of memory at line 21
Simba has eaten my memory:


Warning : running this script will likely crash your simba and flood your RAM.
program new;
{$I SRL/srl.simba}
{$I srl/srl/misc/debug.simba}

procedure FPP_test(const SD, ED, MinR, MaxR: Extended);
var
a ,bmp,w,h,radius ,t:integer;
tpa,temp :TPointarray;
M : TPoint;
begin

w := 300;
h := 300;
M := Point (w/2,h/2);
radius := (min(w,h))/2-10;
bmp := CreateBitmap(w,h);

for a:= 0 to radius do
begin
temp := TPAFromCircle(m.x,m.y,a);
tpa := combineTPA(tpa,temp);
end;
DrawTPABitmap(bmp,tpa,clWhite);
FilterPointsPie(tpa,SD, ED, MinR, MaxR,m.x,m.y);
DrawTPABitmap(bmp,tpa,clred);
Debugbitmap(bmp);

FreeBitmap(bmp);
end;
var
a,b : integer;
begin
for a:= 0 to 360 do
FPP_test(a,a+5,1,150);

end.

Taken memory value was growing up during script run ,and it wasn't freed (from RAM),when script was executed. After investigation I found the culprit:


Changing
 tpa := combineTPA(tpa,temp);
to
combineTPAWrap(tpa,temp,tpa);
decreased memory leak:
and
temp := TPAFromCircle(m.x,m.y,a); 
TPAFromCircleWrap(m.x,m.y,a,temp);
eliminated it fully:

Conclusion:

I didn't test it ,but I suspect more functions may have leaks.
It was said before ,that wrappers theoretically increases function's speed. But no one said ,that using functions without wrappers is dangerous and can explode your RAM!

bg5

2012-05-11 05:13:19

Another one:
program new;
var
tpa1 , tpa2 : TPointArray;
a : integer;
begin
SetLength(tpa1,10000);
for a := 0 to 10000 do
tpa2 := CopyTPA(tpa1);
end.

masterBB

2012-05-11 05:21:56

How interesting.

Leaking function:

function ps_CombineTPA(const Ar1, Ar2: TPointArray): TPointArray; extdecl;
begin
result := CombineTPA(ar1,ar2);
end;

Not leaking procedure:

procedure ps_CombineTPAWrap(const Ar1, Ar2: TPointArray; var Res : TPointArray);extdecl;
begin
Res := CombineTPA(Ar1,Ar2);
end;

Wizzup?

2012-05-11 06:00:43

Try the same thing in lape? ( Use http://nala.villavu.com/downloads/master/81e8bd8e809101372b63b08925275de33e9d3822/ )

masterBB

2012-05-11 06:08:20

Time to move on to lape. Pascalscript doesn't seem to free the variables loaded in the return statement…

nielsie95

2012-05-11 10:29:02

So that's why there are wrapping functions for PS! Raymond should have told us :p

euphemism

2012-05-11 11:30:25

I remember this leak, do you remember this leak, Wizzup?

Brandon

2012-05-11 11:50:46

You aren't supposed to use the non-wrappers.. Not sure why they are exported in the first place..

If you try to use GetTextAtEx(….) it will tell you invalid parameters even if they are correct. This is because you have to use the GetTextAtExWrap(….) which takes the same parameters anyway and works.

The other functions don't telll you this but yeah. Don't use the non-wrappers.

A function without a wrapper could define all sorts of global variables then its the wrapper's function to set them and free them after use.

Biggest example I could think off of the top of my head would be the:

"Create_CTSInfo_helper" which acts as the function..

AND

"SimilarColors" which is the wrapper.

Create_CTSInfo_helper allocates all the memory for the CTS Structs/Classes/Records.
Similar Colors then uses it and passes it to various ColorSame_CTS# functions and then free's it. If Create_CTSInfo_helper was actually exported, you'd have a ton of memory leaks by users who use it directly. Because all the freeing is done in SimilarColors. I'd suspect the same is done for those wrappers you guys mentioned as well..

bg5

2012-05-11 12:25:47

It should be somewhere sticked with big red letters ,that using non-wrappers is forbidden! Most scripters here don't know it ,and they accuse for all runescape catches. :P

Btw.
Not all functions has wrappers. Basically only functions from tpa.pas have them. So if it is PS issue , using inconspicuous functions from other modules like math.pas will also inevitably build slowly memory stack? Am I right?

masterBB

2012-05-11 13:05:19

From: Brandon
Create_CTSInfo_helper allocates all the memory for the CTS Structs/Classes/Records.
Similar Colors then uses it and passes it to various ColorSame_CTS# functions and then free's it. If Create_CTSInfo_helper was actually exported, you'd have a ton of memory leaks by users who use it directly. Because all the freeing is done in SimilarColors. I'd suspect the same is done for those wrappers you guys mentioned as well..


Well, no, not exactly. I might be wrong though, but this is how the CTS functions work:

The Create_CTSInfo function (or Create_CTSInfo_Helper) is only used within mml, there is no leak there. Also, the only thing that function does is converting the color to the color the cts methods needs and set ups the tolerance in CTS. Nothing else. The reason why there is an allocate memory call instead of just creating a new object of the given record is cause the function can return different records. It is true that this is freed in SimilarColors, but this is not related to the wrapper functions.

Let me quote myself:
From: masterBB
Leaking function:

function ps_CombineTPA(const Ar1, Ar2: TPointArray): TPointArray; extdecl;
begin
result := CombineTPA(ar1,ar2);
end;

Not leaking procedure:

procedure ps_CombineTPAWrap(const Ar1, Ar2: TPointArray; var Res : TPointArray);extdecl;
begin
Res := CombineTPA(Ar1,Ar2);
end;


This is where the functions are prepared to be feeded to pascal. As you might notice there isn't a free statement here. The only difference is that the Result variable is defined in the simba script when using the wrapper and is defined by pascalscript when not using the wrapper. Though integers and boolean obviously get freed, custom types don't seem to get the same treatment. The Result var containing a TPA, will not be freed.

Brandon

2012-05-11 13:27:59

BB I don't understand that.. One just calls the other and assigns it to a parameter.. There is no difference there :S
I think you mean the var in the wrapper gets freed but the result in the non wrapper isn't freed. The other way around :S
Since the non wrapper is leaking..

masterBB

2012-05-11 13:33:44

Maybe I wasn't clear ;)

case of the wrapper:

> var myTpa:TPointArray;

> CombineTPAWrap(x,y,myTPA);

>> ps_CombineTPAWrap(x,y,myTPA);

> You will have your new TPA! And it will be freed at the end of your procedure.

case 2, no wrapper:

> var myTpa:TPointArray;

> myTpa := CombineTPA(x,y);

>> ps_CombineTPA(x,y);

>>> A result var will be created to hold the vallue

> You will have your new TPA! And your tpa will be freed at the end of your procedure, the one in the result should have been freed, but it is not.

edit:
Well it is not really like this, but this is a simplification.

Wizzup?

2012-05-12 10:13:10

From: Brandon
BB I don't understand that.. One just calls the other and assigns it to a parameter.. There is no difference there :S
I think you mean the var in the wrapper gets freed but the result in the non wrapper isn't freed. The other way around :S
Since the non wrapper is leaking..


That's exactly the problem. PascalScript doesn't clean up the arrays when they're passed as a result. So it makes a huge difference, because Pascalscript is so flawed.

From: euphemism
I remember this leak, do you remember this leak, Wizzup?


I very much do. ;)

xtrapsp

2012-05-12 10:33:17

So when exactly are we moving to lape? Haha

Bit weary of lape tbh :p just learnt pascal and all :p

Le Jingle

2012-08-07 02:18:47

(Under 3 months) ^.^

Also, iirc I read on the simba news/development that the switchover to lape is a near-future (as of now, 'least I think) reality. I've been running into memory leaks, from the simplest of scripts; plus I noticed the op's script here still leaks memory. I mean no disrespect, I am thankful for pascalscript (;
(I followed my memory leak thread [after my simba crashed]; from Bam Bam's post that lead me here.)