• 🏆 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!

[JASS] Just a question about nulling

Status
Not open for further replies.
Level 8
Joined
Aug 2, 2008
Messages
193
If you have:

JASS:
functiom blabla takes unit U returns nothing
//....
endfunction

You do not have to null these unit.
But if you use it so:

JASS:
functiom blabla2 takes nothing returns nothing
local unit u = GetTriggerUnit()
endfunction

You should null this local variable, because it will leak, when the unit, which has this value will be removed from game.
I also recommend you to null these variables:
units, groups, strings, players, timers, effect (they have a huge leak), locations, forces (playergroups).
 
Level 10
Joined
Aug 19, 2008
Messages
491
grim001 @ wc3c.net said:
Function parameters get their reference counters decremented when the function goes out of scope, unlike handle variables declared at the top of the function.
In other words, the variables* you see after 'takes' does not need nulling.
*The correct term is parameters

--
I also recommend you to null these variables:
units, groups, strings, players, timers, effect (they have a huge leak), locations, forces (playergroups).
You can't null a string, nor remove it from the game in any way

What needs nulling: Every handle. So don't null integers, reals or strings.
Nope, only handles who are removed from the game at some point needs nulling. Permanent handles like players, and in most cases triggers, does not need it (if a unit never dies in the game you won't need to null locals refering to it either).
However it's good to make it into an automated process just for practice...
 
Last edited:
Level 17
Joined
Mar 17, 2009
Messages
1,349
No... actually every local once done from needs to be nulled otherwise it leaks... except in the case of reals, integer, and strings.

Nulling the local has nothing to do with whether the parameter still belongs to the game or not... it only has to do with the fact of whether the local variable still holds any information about that parameter or not.

So I emphasize on the need of nulling every local variable after it gets used!
 
Last edited:
Level 11
Joined
Feb 22, 2006
Messages
752
Nulling locals does nothing if the handle they point to is never destroyed. Handle locals themselves are just a 4 byte index, and that info does get garbage collected once the function goes out of scope.

However, wc3's handle allocation system (which assigns each handle a unique id) fails to decrement a handle's reference count (basically how many pointers are referencing it) when a non-null handle local is automatically garbage collected. So basically once this happens, a handle's reference count can never reach 0, meaning its id will never be freed up for reallocation since the system still thinks the handle is in scope. Even after the handle is destroyed, the id will still not be reallocated; this is the "leak": the wasted handle index.

So from this, you can obviously see that if a handle is never destroyed, not nulling locals that point to it doesn't leak since a handle id won't ever be a candidate for reallocation anyway if the handle still exists.
 
Level 10
Joined
Aug 19, 2008
Messages
491
I've got a good quote from vexorian which should help explain the matter, if azinricepuff's post didn't:
Vexorian said:
First of all, always null handle local variables when they reach the end of their 'scope', always. Plenty of times, it is not necessary to null a local. But turning the nulling into a mechanical process while trivializing it is better than having to give thought to such a lame thing... Just to save a couple of lines of code...


However, if this is your typical spell trigger, it is true you don't have to null it.

First of all, you are not worried about the pointer itself leaking, the reason you null locals is because of the handle's index.

The first thing to notice is that handle indexes are ref-counted , even if you call a Destructor (IE RemoveLocation) on a handle, its index will remain alive until all references against it are down. When you call a Destructor, a 4 bytes handle "ghost" will remain in its location.

What happens here, is that there is a blizzard bug, references for local variables don't go down automatically when a function's scope ends. So we set them to null so the reference counter goes down, and the index can be recycled (and we can get those 4 bytes back)

The bytes are not an issue unless you have this leak multiple times, however, the indexes are a problem.


JASS:
function err takes nothing returns nothing
 local location loc = Location(0, 4.5)
   call RemoveLocation(loc)
endfunction

This line of code leaks. We are removing the location object, however, the bug prevents wc3 to notice loc's index is no longer in use. And thus this index will leak.

JASS:
function err takes nothing returns nothing
 local location loc = Location(0, 4.5)
   call RemoveLocation(loc)
 set loc = null
endfunction
This does not leak anymore.

Anyway, if the handle held by the variable is not EVER destroyed, then you don't have to null it. That's the real reason that in the case you pointed, you don't need to null the variable.
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
Oh, so basically those 4 bytes don't appear unless we use a destructor? What I thought is that you could free up those 4 bytes which basically form the local, while keeping the handle roaming around...(since I tested that with GetHandleId() and it returns 0, but guess that is irrelevant). :p
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
When you null the variable. The four bytes are cleared.
Corrected: the four bytes are set to 0. "Cleared" makes it sound like they're no longer in memory.

Nulling does not free up the memory used by those 4 bytes. Garbage pointers are automatically collected similarly to how integers, reals and boolean variables are collected when a function returns.
 
Status
Not open for further replies.
Top