As far as I know, they do not leak.
As far as I know, they do not leak.
function example takes player p returns nothing
local player someone = p
endfunction
I think your correct.
If a variable is set to a value which is then used as a parameter for a function and the variable is nullified after the function returned the value,
Then nullifying the parameter won't make any difference since a paramater is never stored, only used inside the function.
So a parameter doesn't get stored, it only gets used.
For example:
JASS:function example takes player p returns nothing local player someone = p endfunction
Here you store a variable with the value of the parameter. Which means the variable can leak, however p does not since it's only used inside the function.
(I don't get why anyone wants to store a variable to be the value of the parameter since the parameter can be used... But that's not the point here)
but local group g after must be nulled at end after destroying
function example takes group g returns nothing
// do something with g here, it doesn't need to be nullified because it is a parameter which is never stored, only used...
endfunction
function example1 takes nothing returns nothing
local group g = some random group
call example(g)
call DestroyGroup(g)
set g = null
endfunction
Who are you Hashjie? Noone here should know that things.
function testfunc2 takes player p returns nothing
set p = Player(1)// now insite the function we change the variable
if( p == Player(1) ) then// to test that it really changes
call DB("jep it really changes")
endif
endfunction
function testfunc1 takes nothing returns nothing
local player p = Player(0) // we have our variable
call testfunc2(p) // we pass it as parameter
if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
call DB("fuck")
endif
endfunction
why do you think it does not get stored? u have some logic behind it? prove?
i ask because i made following test which kinda could be kind of a disprove to ur theory... : /
i would actually have thought too that the parameters are just pointers but the following test shows that it is actually 2 different values
so it is stored?
JASS:function testfunc2 takes player p returns nothing set p = Player(1)// now insite the function we change the variable if( p == Player(1) ) then// to test that it really changes call DB("jep it really changes") endif endfunction function testfunc1 takes nothing returns nothing local player p = Player(0) // we have our variable call testfunc2(p) // we pass it as parameter if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !! call DB("fuck") endif endfunction
i do not trust in what Hashjie sais
is there some pro who has more knowledge about this?
it must be that this parameter and the variable from my example are stored in different parts of memory... since we change one without changeing the other
i did spam this example above in a very fast loop and with 500 actions attached, it does not seem to increase the memory usage when u look at system monitor, also does not make the waittime to enter the chat channels longer
though i also tested without nullifying p at all and no difference^^
ummm... i duno rly lol
mb someone else has any idea?
im not guna keep researching this since i dont have any lags in my map or anything...
Maker said:As far as I know, they do not leak.
alfalfa said:it must be that this parameter and the variable from my example are stored in different parts of memory... since we change one without changeing the other
Search2Destroy said:Learn pointer. I think parameter in wc3 send parameter by reference.
wikipedia said:In computer science, a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address.
For high-level programming languages, pointers effectively take the place of general purpose registers in low-level languages such as assembly language or machine code, but may be in available memory.
A pointer references a location in memory, and obtaining the value at the location a pointer refers to is known as dereferencing the pointer.
A pointer is a simple, more concrete implementation of the more abstract reference data type.
Several languages support some type of pointer, although some have more restrictions on their use than others.
As an analogy, a page number in a book could be considered a pointer to the corresponding page; dereferencing such a pointer would be done by flipping to the page with the given page number.
wikipedia said:In computer programming, a parameter is a special kind of variable, used in a subroutine to refer to one of the pieces of data provided as input to the subroutine.
[1] These pieces of data are called arguments.
An ordered list of parameters is usually included in the definition of a subroutine, so that, each time the subroutine is called, its arguments for that call can be assigned to the corresponding parameters.
Just as in standard mathematical usage, the argument is thus the actual value passed to a function, procedure, or routine (such as x in log x), whereas the parameter is a reference to that value inside the implementation of the function (log in this case).
In the most common case, call-by-value, a parameter acts within the subroutine as a local (isolated) copy of the argument, but in other cases, e.g. call-by-reference, the argument supplied by the caller can be affected by actions within the called subroutine (as discussed in evaluation strategy).
The semantics for how parameters can be declared and how the arguments get passed to the parameters of subroutines are defined by the language, but the details of how this is represented in any particular computer system depend on the calling conventions of that system.
NOT a reference to a value stored somewhere in the memory of the computer, but a reference to the value inside the implementation of the function!wikipedia said:In computer science, a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address.
Just as in standard mathematical usage, the argument is thus the actual value passed to a function, procedure, or routine (such as x in log x), whereas the parameter is a reference to that value inside the implementation of the function (log in this case).
wikipedia said:a parameter acts within the subroutine as a local (isolated) copy of the argument
alfalfa said:why do you think it does not get stored? u have some logic behind it? prove?
parameters doesnt leak
If your refferencing to this:the variables that is used to pass to that parameter that is not
destroyed, nulled leaks...
function testfunc1 takes nothing returns nothing
local player p = Player(0) // we have our variable
call testfunc2(p) // we pass it as parameter
if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
call DB("fuck")
endif
endfunction
Hashjie would you be intrested joining my map project?
the projects goal is to become the most played map on wc3 battle.net , even more played then legion td , it will replace legion td and leave it in the dust
if your intrested, contact me on skype, my nick is "d3cammy" and my skype picture is allways a cat
even units need not to be nulled although they leak but very little, I've tested to createThen your incorrect, local player handles never need to be nulled.
If you meant in generall they need to be destroyed and nulled, then sorry :S
sometimes the function with the
nulled varible consumes more ram usage than the non-nulled...
even units need not to be nulled although they leak but very little, I've tested to create
3000+ units many times, still the leak is very minimal
correct, its Highly recommended but not a must ...Hmm even so, better to just do it. It doesn't hurt...
correct, its Highly recommended but not a must ...
sample?, see our topic on post starting on Post25
Confinement
I still don't understand how a non-nulled instance can be less then a nulled one :S
How can something that's not empty take up less RAM memory then something that's empty?? For me, that's a mystery xD
scope testu initializer init
globals
integer I = 0
endglobals
function TestU takes nothing returns nothing
local unit u
set I = I+1
if I < 3000 then
set u = CreateUnit(Player(0), 'hpea', 0,0,0)
call KillUnit(u)
else
call DestroyTimer(GetExpiredTimer())
endif
endfunction
function init takes nothing returns nothing
call TimerStart(CreateTimer(), 0.03, true, function TestU)
endfunction
endscope
me too but I've tested it a month ago and it happened 'only sometimes'
I did something like this...
JASS:scope testu initializer init globals integer I = 0 endglobals function TestU takes nothing returns nothing local unit u set I = I+1 if I < 3000 then set u = CreateUnit(Player(0), 'hpea', 0,0,0) call KillUnit(u) else call DestroyTimer(GetExpiredTimer()) endif endfunction function init takes nothing returns nothing call TimerStart(CreateTimer(), 0.03, true, function TestU) endfunction endscope
maybe the dead unit is automatically nulled???...
JASS:function testfunc2 takes player p returns nothing set p = Player(1)// now insite the function we change the variable if( p == Player(1) ) then// to test that it really changes call DB("jep it really changes") endif endfunction function testfunc1 takes nothing returns nothing local player p = Player(0) // we have our variable call testfunc2(p) // we pass it as parameter if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !! call DB("fuck") endif endfunction
Damn it, i got parameter pass by value -.-" i get both DB output.
function testfunc2 takes player p returns nothing
set p = Player(1)// now inside the function we change the VALUE of the PARAMETER, NOT the VARIABLE
if( p == Player(1) ) then// to see if Player(1) == Player(1)...
call DB("wait, what?")
endif
endfunction
function testfunc1 takes nothing returns nothing
local player p = Player(0) // Here we create a variable and set it to Player(0)
call testfunc2(p) // Here we pass the VALUE of the variable to the PARAMETER of the function
if( p == Player(0) ) then// now back here , the variable did not change because we didn't change the variable at all, we only changed the VALUE of the PARAMETER in testfunc2
call DB("fuck, this is supposed to happen")
endif
endfunction
Yep. You are right. If im not mistaken... Now there is two memory location of p -.-"
afaik, pointer store the address of the memory location. passed value must store in another location since it doesnt change the original one. if it is not variable. how can it act as variable. my head messed up now. ill revise this topic -.-" lol
why do you think it does not get stored? u have some logic behind it? prove?
i ask because i made following test which kinda could be kind of a disprove to ur theory... : /
i would actually have thought too that the parameters are just pointers but the following test shows that it is actually 2 different values
so it is stored?
JASS:function testfunc2 takes player p returns nothing set p = Player(1)// now insite the function we change the variable if( p == Player(1) ) then// to test that it really changes call DB("jep it really changes") endif endfunction function testfunc1 takes nothing returns nothing local player p = Player(0) // we have our variable call testfunc2(p) // we pass it as parameter if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !! call DB("fuck") endif endfunction
function testfunc1 takes nothing returns nothing
function testfunc2 takes player a returns nothing
set a = Player(1)// now insite the function we change the variable
p=a
if( p == Player(1) ) then// to test that it really changes
call DB("jep it really changes")
endif
endfunction
local player p = Player(0) // we have our variable
call testfunc2(p) // we pass it as parameter
if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
call DB("fuck")
endif
endfunction
function testfunc takes nothing returns nothing
local p=1
function testfunc_bis takes nothing returns nothing
local p=2
if( p == 2 ) then// returns true!
call DB("I can see only 2nd one!")
endif
endfunction
endfunction
hmm. This is weird language. First time see that function can't be local..
hmm. This is weird language. First time see that function can't be local..
but u can call functions from function
also u are able to make global functon in normal we too, if u write ur function to header then u can call it to any trigger
Thats actualy normal.
function hi takes unit a, unit b, unit c, unit d returns nothing
endfunction
function hi takes nothing returns nothing
local unit a
local unit b
local unit c
local unit d
set a = null
set b = null
set c = null
set d = null
endfunction
- Locals leak, null them
- Parameters don't leak, you don't need to null them
- Parameters can be modified as if they were locals without affecting the original variable passed by another function
That's exactly what I've explained like 5 times in a row.
I hope people will finally understand how it works.
This thread has been going on for way to long now.
huge maps like DotA, that have more than 26.000 lines of cleaned and optimized code
I think it's because units are being removed from the game after 60 second expiration timer on their decaying corpse.
Causing the unit to be removed from the memory and therefore does not need to be nulled.
Meaning that if you'd null the variable it's the same as a Do Nothing
I'm gonna test that later on...
function CheckRemainingTime takes timer WhichTimer returns string RemainingTime
local integer RemainingTime
call PauseTimer(WhichTimer)
set RemainingTime = R2I(TimerGetRemaining(WhichTimer))
call ResumeTimer(WhichTimer)
return I2S(RemainingTime)
endfunction
function CheckTime takes nothing returns nothing
local string remainingtime
set remainingtime = CheckRemainingTime(udg_UnitExpiration)
call DisplayTextToPlayer(Player(0), 0, 0, remainingtime)
if remainingtime == "0" then
set udg_Expired = true
call PauseTimer(udg_UnitExpiration)
call DestroyTimer(udg_UnitExpiration)
endif
endfunction
function Trig_Untitled_Actions takes nothing returns nothing
local timer t = CreateTimer()
local unit u = CreateUnit(Player(0), 'hpea', 0,0,0)
set udg_UnitExpiration = CreateTimer()
call KillUnit(u)
call TimerStart(udg_UnitExpiration, 60, false, null)
call TimerStart(t, 1, true, function CheckTime)
loop
exitwhen udg_Expired == TRUE
call TriggerSleepAction(0.5)
endloop
call DisplayTextToPlayer(Player(0), 0, 0, "Unit ID after the expiration timer of the unit has expired: " + I2S(GetHandleId(u)))
call PauseTimer(t)
call DestroyTimer(t)
set t = null
endfunction
//===========================================================================
function InitTrig_Untitled takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterTimerEvent(t, 0.00, false)
call TriggerAddAction( t, function Trig_Untitled_Actions )
set t = null
endfunction
function CreateUnitAndGetShadow takes nothing returns image
// Handle id of this image is now 0
local image i = CreateImage("dummy.blp", 64, 64, 0, 0, 0, 0, 64, 64, 0, 3)
// Image destroyed, i points to 0
call DestroyImage(i)
// This unit will also create an image (it's shadow)
// This shadow will have a Handle Id of 0
// i points to an image with Id 0
call CreateUnit(...)
// Thus i is now the actual shadow of the unit ^_^
return i
endfunction
that's really not true coz I have spells like that and it works fine, besides you- Destroying timers is buggy, that's why TimerUtils is extremely useful.
etc..
scope Nullings initializer init
globals
unit U
integer RTime = 61
endglobals
private function TestIt takes nothing returns nothing
set RTime = RTime - 1
call BJDebugMsg(I2S(RTime))
if RTime < 1 then
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
if U==null then
call BJDebugMsg("nulled")
else
call BJDebugMsg("not nulled")
endif
endif
endfunction
private function init takes nothing returns nothing
set U = CreateUnit(Player(15), 'hpea', 0,0,0)
call KillUnit(U)
call TimerStart(CreateTimer(), 1, true, function TestIt)
endfunction
endscope
cant use TU in jass mode only...
that's really not true coz I have spells like that and it works fine
Just null all variables.
Removing a unit will only make the integer that points to them point to a null struct/class.
It will not make the variables themselves point to null.
That's why something like this:
JASS:function CreateUnitAndGetShadow takes nothing returns image // Handle id of this image is now 0 local image i = CreateImage("dummy.blp", 64, 64, 0, 0, 0, 0, 64, 64, 0, 3) // Image destroyed, i points to 0 call DestroyImage(i) // This unit will also create an image (it's shadow) // This shadow will have a Handle Id of 0 // i points to an image with Id 0 call CreateUnit(...) // Thus i is now the actual shadow of the unit ^_^ return i endfunction
Works perfectly.
However,
Optimizations:
- Remove the == TRUE and == true's in there (100% useless)
exitwhen (udg_Expired)
- Use timers instead of periodic triggers
It's just a Demo code, so there aren't a lot of important improvements.
- TriggerSleepActions are inaccurate and /bad/.
- Destroying timers is buggy, that's why TimerUtils is extremely useful.
etc..
that's really not true coz I have spells like that and it works fine, besides you
cant use TU in jass mode only...
@Hashjie
there's no need for all that conversions...checking the remaining time is as simpel as this...
JASS:scope Nullings initializer init globals unit U integer RTime = 61 endglobals private function TestIt takes nothing returns nothing set RTime = RTime - 1 call BJDebugMsg(I2S(RTime)) if RTime < 1 then call PauseTimer(GetExpiredTimer()) call DestroyTimer(GetExpiredTimer()) if U==null then call BJDebugMsg("nulled") else call BJDebugMsg("not nulled") endif endif endfunction private function init takes nothing returns nothing set U = CreateUnit(Player(15), 'hpea', 0,0,0) call KillUnit(U) call TimerStart(CreateTimer(), 1, true, function TestIt) endfunction endscope
200% agree, but nothing wrong with destroying them, thats why DestroyTimer is there ...Either way, recycling is much better. When using Timer Recyclers, you won't have to constantly destroy and create new timers.