HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Does this leak? (Small amount of code)

11-01-2010, 07:53 PM#1
rogueteddybear
I was wondering if this dummy caster creation code leaked a unit handle.
Specifically at the end of CreateCaster():

Collapse JASS:
library DummyCast

function CreateCaster takes player owner, real x, real y, integer abilid, integer level returns unit
    local unit dummy = CreateUnit(owner,'dCAS',x,y,0) 
    call UnitAddAbility( dummy, abilid) 
    call SetUnitAbilityLevel( dummy, abilid, level) 
    call UnitApplyTimedLife( dummy, 0, 2)
    
    //Am I leaking a unit handle here?
    return dummy
endfunction

function CastAbilityTarget takes player caster, unit target, real x, real y, integer abilid, integer abillvl, string order returns nothing
    local unit dummy = CreateCaster(caster, x, y, abilid, abillvl)
    call IssueTargetOrder(dummy,order,target)
    set dummy = null
endfunction

endlibrary

If it does leak, is there a better strategy?
11-01-2010, 08:08 PM#2
Fledermaus
CreateCaster leaks.

Collapse JASS:
function CreateCaster takes player owner, real x, real y, integer abilid, integer level returns unit
    set bj_lastCreatedUnit = CreateUnit(owner,'dCAS',x,y,0) 
    call UnitAddAbility(bj_lastCreatedUnit, abilid) 
    call SetUnitAbilityLevel(bj_lastCreatedUnit, abilid, level) 
    call UnitApplyTimedLife(bj_lastCreatedUnit, 0, 2)
    return bj_lastCreatedUnit
endfunction

You could use another global unit variable if you're already using that one.
11-01-2010, 08:18 PM#3
rogueteddybear
Thanks for the fast reply! That worked just fine. I'm assuming that global var will not be conflicted over when calling CastAbilityTarget() multiple times (in say, a loop)?
11-01-2010, 08:23 PM#4
Fledermaus
Na, it should be fine. You prolly want to cleanup the unit in CastAbilityTarget though.
call UnitApplyTimedLife(dummy, 'BTLF', 5.) after the IssueTargetOrder should be fine.
11-01-2010, 08:30 PM#5
rogueteddybear
I have a call to that already in the CreateCaster is that fine?
I also do not have any buff or ability with the id 'BTLF'
11-01-2010, 08:34 PM#6
Fledermaus
Oh whoops, I missed that. Yeah that's fine and you don't need a buff matching the ID.
11-01-2010, 08:54 PM#7
Anitarf
To clarify, the code was not leaking a unit handle since the unit got cleaned up when its expiration timer expired, but it was leaking a handle index: due to a bug, local variables are not "set to null" when a function finishes, so the handle index still has a record of those variables pointing to it and does not get recycled because of that. As a result, new indexes must be allocated when new handles are created.

By the way, when dealing with dummy casters, I find xecast incredibly useful, I encourage you to take a look at it.
11-05-2010, 01:37 AM#8
xZetH
The variable dummy inside the function CreateCaster can't be nullified. Leak, or not?

why don't you...
Collapse JASS:
function CastAbilityTarget takes player caster, unit target, real x, real y, integer abilid, integer abillvl, string order returns nothing
    local unit dummy = CreateUnit(caster,'dCAS',x,y,0.)
    call UnitAddAbility( dummy, abilid) 
    call SetUnitAbilityLevel( dummy, abilid, abillvl) 
    call UnitApplyTimedLife( dummy, 'BTLF', 2)    
    call IssueTargetOrder(dummy,order,target)
    set dummy = null
endfunction

?
12-01-2010, 12:03 PM#9
Bribe
Because parameters do not leak handle indexes, this would solve the problem easily:

Collapse JASS:
private function HiddenCreate takes unit u, integer abilid, integer level returns unit
    call UnitAddAbility(u, abilid) 
    call SetUnitAbilityLevel(u, abilid, level) 
    call UnitApplyTimedLife(u, 'BTLF', 2.)
    return u
endfunction

function CreateCaster takes player owner, real x, real y, integer abilid, integer level returns unit
    return HiddenCreate(CreateUnit(owner, 'dCAS', x, y, 0.))
endfunction

However, there is an amazing way discovered to cast spells instantly without having to wait for the dummy to turn to face the target, meaning the same dummy can be used for every spell in the game. It's not much of a secret.