| 08-22-2009, 06:38 PM | #1 |
I'm not sure about one thing. I have a function that returns unit: JASS:function CinemAltarFind takes player whichPlayer returns unit local group tempGroup = GetUnitsOfPlayerMatching(whichPlayer, Condition(function CinemAltarFilter)) local unit altar = GroupPickRandomUnit(tempGroup) call DestroyGroup(tempGroup) set tempGroup = null return altar endfunction I intent to use it somewhere like this: JASS:set someVariable = CinemAltarFind(Player(0)) The problem is that I create a local variable unit, then set it to be random... and return it. I know that handle types are called-by-reference and I know that I should destroy handle types and it is even better to nullify the local variables (that's what I'm doing with tempGroup). As far as I know this doesn't have to be done with parameters that a function takes (don't I have to destroy them?), but what about return types? It would probably be stupid to nullify altar variable, but still I'm not sure if this will cause a memory leak. Can anyone please explain how exactly this works? What happens to the local reference altar and what happens to the unit itself? |
| 08-22-2009, 06:46 PM | #2 |
The local reference would leak. The returned unit (handle) itself has to be cleaned later, by another function. To prevent the reference leak you need something like this: JASS:globals private unit returnunit endglobals function CinemAltarFind takes player whichPlayer returns unit local group tempGroup = GetUnitsOfPlayerMatching(whichPlayer, Condition(function CinemAltarFilter)) local unit altar = GroupPickRandomUnit(tempGroup) call DestroyGroup(tempGroup) set tempGroup = null set returnunit = altar set altar = null return returnunit endfunction You probably need to do better than GetUnitsOfPlayerMatching, that BJ has a memory leak of its own. |
| 08-22-2009, 07:07 PM | #3 |
thanx, what about this: JASS:function CinemAltarFind takes player whichPlayer returns nothing local group tempGroup = CreateGroup() call GroupEnumUnitsOfPlayer(tempGroup, whichPlayer, Condition(function CinemAltarFilter)) set udg_altar = GroupPickRandomUnit(tempGroup) call DestroyGroup(tempGroup) set tempGroup = null endfunction Will this leak? Now udg_altar is just a global unit, but I'm not sure about the boolexpr used as filter... |
| 08-22-2009, 08:51 PM | #4 |
Condition() returns a boolexpr, which you would have to destroy every time it has been used. Or you could use the same boolexpr every time, if you create it at map initialization. |
| 08-22-2009, 08:59 PM | #5 |
Condition and Filter return the same boolexpr for the same code every time. No leaks there. If you destroy it, future attempts at using it won't work[citation needed]. Never again. Try testing this: JASS:scope Test initializer Init private function Actions takes nothing returns boolean if Condition(function Actions) == Condition(function Actions) then call BJDebugMsg("Condition(function Actions) == Condition(function Actions)") else call BJDebugMsg("Condition(function Actions) != Condition(function Actions)") endif if Filter(function Actions) == Filter(function Actions) then call BJDebugMsg("Filter(function Actions) == Filter(function Actions)") else call BJDebugMsg("Filter(function Actions) != Filter(function Actions)") endif if Filter(function Actions) == Condition(function Actions) then call BJDebugMsg("Filter(function Actions) == Condition(function Actions)") else call BJDebugMsg("Filter(function Actions) != Condition(function Actions)") endif return false endfunction private function Init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterPlayerEvent(t, Player(0), EVENT_PLAYER_END_CINEMATIC) call TriggerAddCondition(t, Condition(function Actions)) endfunction endscope |
| 08-22-2009, 10:08 PM | #6 | |
Quote:
If you use And() it will "leak" and DestroyBoolexpr will do something, but if you used Condition() it seems to do nothing. |
| 08-23-2009, 08:55 AM | #7 | ||
Quote:
GetUnitsOfPlayerMatching:function GetUnitsOfPlayerMatching takes player whichPlayer,boolexpr filter returns group local group g = CreateGroup() call GroupEnumUnitsOfPlayer(g, whichPlayer, filter) call DestroyBoolExpr(filter) return g endfunction As you see they did destroy the boolexpr in that BJ (I didn't when I switched to GroupEnumUnitsOfPlayer). And it worked as many times as wanted while I was using GetUnitsOfPlayerMatching, there just was that unit group reference leak. As boolexpr filter I use Condition(function CinemAltarFilter) where function CinemAltarFilter is always the same defined at map initialization. The code used to create boolexpr is always the same, but whereas code is native and cannot leak, boolexpr is handle. So I don't know whether it creates new boolexpr from the same code every time it is used (it would probably leak). Quote:
|
