• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Things That Leak

Does that destroy the last created unit group or how does it work exacly?

Take a look at this blizzard function.

JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction

See, if you setbj_wantDestroyGroup to true and call ForGroupBJ then it will destroy the group.

I think it would be best to avoid this way of destroying groups, though.
 

sentrywiz

S

sentrywiz

Floating texts also leak but I understand there is a 100 limit on it so I guess its more of a performance issue rather than a possibility to crash.

Also INIT triggers are called once on start of the map for keeping of vars, creation of stuff and they are never called again (except maybe at end of game in some cases) so this is not a OMG LEAK CLEAN IT UP!
 
Level 8
Joined
Oct 2, 2013
Messages
288
I noticed that when you use a power-up item (tome of power for instance) it leaves a small yellow dot on the ground from the flashy effects. This dot does not vanish.
Is this considered a leak?

I considered changing the item model into a zone indicator. But wouldn't the effect still leak even though you cant see it?
 
Level 5
Joined
Jan 6, 2010
Messages
115
  • waypointA1
    • Events
      • Unit - A unit enters waypoint1 <gen>
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 2 (Blue)
    • Actions
      • (Unit - Order (Triggering unit) to Attack-Move To (Center of waypont2 <gen>))
Quick question. Is the following the correct way of stopping the above leak?

  • waypointA1
    • Events
      • Unit - A unit enters waypoint1 <gen>
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 2 (Blue)
    • Actions
      • Set UnitVar = (Triggering unit)
      • (Unit - Order (UnitVar) to Attack-Move To (Center of waypont2 <gen>)
      • Custom script: call DestroyGroup(udg_UnitVar)
 
Using "TriggeringUnit" does not leak. Storing it into a unit variable makes sense, if you use it more than once in further actions to avoid more function calls.
(TriggeringUnit calls a function each time, so: using variable > function calls)

But back to your leak question, you actually leak a location. Store the point into a variable, and remove the location afterwerds. Read the "Location" chapter in this tutorial.
("Center of waypont2" leaks)

Also, "call DestroyGroup()" is only used for UnitGroups. You don't have any UnitGroup here.
 
Level 5
Joined
Jan 6, 2010
Messages
115
I meant to write DestroyUnit or something, but that's seemingly irrelevant as it's the location variable that leaks.
Let me do another attempt...

  • waypointA1
    • Events
      • Unit - A unit enters waypoint1 <gen>
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 2 (Blue)
    • Actions
      • Set TempLocation = (Center of waypont2 <gen>)
      • (Unit - Order (Triggering unit) to Attack-Move To (TempLocation))
      • Custom script: call RemoveLocation(udg_TempLocation)
 
Level 5
Joined
Jan 6, 2010
Messages
115
Brilliant! thanks.

Oh, one more question. Is it enough to have a single "TempLocation" variable if it's a lot of similiar triggers going on practically at the same time? None of them has any wait-functions, so I presume a single trigger is always finished before another starts?
 
Level 5
Joined
Jan 6, 2010
Messages
115
Gotcha.
As I started going through the triggers and plug the leaks, yet another thing came to mind. Sorry about all the questions, hope you bear with me! :) I would totally Rep you if I could at the moment.

If I always use use Set TEMP_Point = (Some Point <gen>) and always make this point the target of the orders, is it really necessary to use RemoveLocation()? I mean, will it not then overwrite the information each time, taking no extra memory space?
 
If you're using a "temp" variable, I would say yes. Because you must pay attention here. You must ensure that you free the memory before you set your variable to a new value.

Set tempLoc = CentreOf_A
...
Set tempLoc = CentreOf_B
call RemoveLocation(udg_tempLoc)
^leak because I didnt free memory before I reused the variable.

For constant unit patrols it would make sense to use location variables which gets initialized once and will never be overwritten again or destroyed.

Init-trigger:
Set RunPoint1 = CentreOf_A
Set Runpoint2 = CentreOf_B

A Unit Enters Region1
Unit - Order TriggeringUnit Move to RunPoint1

A Unit Enters Region2
Unit - Order TriggeringUnit Move to RunPoint2

So in these three triggers you see I set the points once, and they never get touched again. If you can ensure this, then you can do like this.

Contra is that you need to create more variables instead of only one "temp" variable.

If you have more questions you can directly message me to discuss it. :csmile:
 
Two triggers may run "at the same time" even if there is no wait. It happens when an action done in a trigger triggers the event of another one.
Example :
  • Events
    • Player - Some random event
  • Actions
    • Player - Display "Step 1" to (All Players)
    • Unit - Order UNIT to move to LOCATION
    • Player - Display "Step 3" to (All Players)
  • Events
    • Unit - A unit is given an order targeting a point
  • Actions
    • Player - Display "Step 2" to (All Players)
The texts are displayed in the order 1, 2, 3 there (the second trigger runs in the middle of the execution of the first, which resumes once this second trigger's run is over).

This kind of situation is not that much frequent but it can be troublesome (and generate more bugs than a simple memory leak). Be cautious with giving orders, giving/removing items and moving units in particular.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
But removing an item (and widget in general) is not something instant, right ?
However killing is instant i think.

I also remember i had an hard time debugging a special case, i tried to ordered an unit (no target, or widget target, or point target) on some order event (no target, or widget target or point target), but the order was not instant and then the check was screwed, but maybe it was just because i paused the unit (can't remember if i paused it or not).
 
I don't remember about the "remove unit" thing. I think the unit is physically removed from the game instantatly (maybe triggering some "death" events or some order events, when they have skills like "defend") and the datas and handle are flushed after a 0 wait. But that's barelly a guess.

For the order, I think it's because it was stuned or paused indeed ^^
Orders given while a unit is stunned are activated only once the stun ends. That I remember.
 
No, sometimes it makes sense to use it like a "constant" point variable. So you never change them, then you don't need to remove them.

If you still wanna refer to the same location later, just let it be. But if you can't ensure that you won't use it in an other trigger (so overwrite the value) then directly remove it after usage.

Basicly for constant spawns/teleport locations it can make sense just to create extra point variables, set them once in init, and then never remove them.

But if you only need it temporary just do it like in the example.
 
Level 4
Joined
May 9, 2010
Messages
50
  • Custom script: set bj_wantDestroyGroup = true
  • Group - Pick every unit in (Random 1 units from BlackTornado_Group) and do (Actions)
Is that leak? Cause it use additional function GetRandomSubGroup, which use local group g and do not destoy it.
 
Level 8
Joined
Mar 12, 2008
Messages
437
Do local variables leak?

Say I have a function like this
JASS:
function CreateCreeps takes arguments returns group
    local group ug
    // some actions
    return ug
endfunction

Will it always leak when called? Since you want to clean the leak every time you call it, it would be convenient to include the cleaning in the script. Is that possible?
 
Level 8
Joined
Mar 12, 2008
Messages
437
Not the variable itself, but you will probably reference a real group object with it, therefore increase the reference counter of the object and when the local variable runs out of scope before resetting it, that won't be reverted.

Hm.. so what happens when I use this function in a context? For example,
JASS:
call CreateCreeps( someArgument )

JASS:
set udg_awesomeGroup = CreateCreeps( someArgument )
call DestroyGroup( udg_awesomeGroup )

So do these leak? I just want to make sure whether simply calling the group-generating function causes a leak.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
it still leaks, because the group you returned has not been dereferenced.

This is not the same as object living out of scope. You have to destroy the group after you are done with it(or never, if the group is meant to be for the whole map), but there is another leak. This leak will leak 4 bytes of memory every time you destroy your group and you failed to set all variables that pointed to it to null.

So yes, your example will leak 4 bytes, because blizzard forgot to null local variables when they fall out of scope(you go out of function).

However, this is not something you should be worried about, because the way to prevent this is so stupid noone should bother, ever
 
Top