HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Leaking Variables...

09-07-2007, 11:30 AM#1
darkwulfv
Ok. Does a local which does not get used, but is nulled at the end of the function, leak?

Example:
Collapse JASS:
local unit u
//Actions
if A == true then
set u == something
endif
//More stuff
set u = null

Now, let's say 'A' is NOT equal to true when this runs. According to War3err, 'u' would be an uninitialized variable. Since it's nulled anyways, does that leak at all?

While I'm at it, is there a dummy value I could set something like an effect variable to (would null work?), so that I don't get War3err errors everytime a passive runs and doesn't set the effect variable to anything (because it didn't pass the check)?
09-07-2007, 12:26 PM#2
Strilanc
You've misunderstood what a leak is. Technically, variables don't leak, what they point at can be leaked. http://en.wikipedia.org/wiki/Memory_leak

Essentially, you create some structure, then lose any reference to it. Now you can't find it to clean it up, but its still sitting in memory. (It will be cleaned when the game ends, because WC3 keeps track of it. If WC3 leaks it too, your OS will clean it when WC3 ends.)

I doubt there is any map ever that leaked units. It would be incredibly obvious when units started being created constantly but never removed. Also, you can't lose the reference to a unit because you can iterate over all of them.
09-07-2007, 01:16 PM#3
Toadcop
+ the object IS removed ! BUT the handle of this object is not recycled (generic handles units,triggers etc.). END of the story.
// if you use gamecache so any new handle will create (in gc usage) new string == extra memory needed. in truth it's not really seriously.
09-07-2007, 01:41 PM#4
Vexorian
Quote:
You've misunderstood what a leak is. Technically, variables don't leak, what they point at can be leaked

It is not that easy. Since Jass allows/requires the user to destroy objects it could cause access violations if you tried to do something on a handle that was already removed. What war3 does is to use a reference counter for the handle objects, if you remove a handle it gets replaced with some 4 bytes ghost that holds that memory space until no variable references to it.

The problem is, that for some odd reasons blizzard does not decrement the reference counter when locals go out of scope, so you need to set them to null else these ghosts will leak and your handle ids will raise unnecessarily high.

Not a believer? try this:

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

function B takes nothing returns nothing
 local location loc=Location(0,0)
     call RemoveLocation(loc)
 set loc=null
endfunction

Compare memory usage by A and B.

In this case , darkwulfv if the variable is not ever assigned (not confuse with used) it will not even require to be assigned to null. But if it does get assigned to a handle that is "living" then it requires to set to null.

If you take a local variable, do not ever use it and then assign it to null by the end of the function, it doesn't 'leak'
09-08-2007, 03:32 AM#5
darkwulfv
Ok, Vex answered my question plain and simple. Thank you.
09-08-2007, 03:51 AM#6
Strilanc
Quote:
Originally Posted by Vexorian
depressing words...

I assumed Blizzard would actually do that correctly. I guess I should have picked up on the pattern by now.

I guess I'm too used to languages like C spoiling me with memory management (that is sarcasm, by the way).
09-08-2007, 08:40 AM#7
Anitarf
Quote:
Originally Posted by darkwulfv
Now, let's say 'A' is NOT equal to true when this runs. According to War3err, 'u' would be an initialized variable.
Doesn't War3err only warn you of uninitialized variables?
09-08-2007, 11:26 AM#8
botanic
World Edit would only stop you if the number is not initialized. The value of u would be initialized so there would be no error...
09-08-2007, 12:02 PM#9
Captain Griffen
WE wouldn't detect it.
09-08-2007, 02:28 PM#10
darkwulfv
Damn typo! I meant:

Quote:
Originally Posted by Me
Now, let's say 'A' is NOT equal to true when this runs. According to War3err, 'u' would be an uninitialized variable.
09-08-2007, 04:46 PM#11
Anitarf
Allrighty then, let's review. War3err tells you you have an uninitialized variable. That's very bad, because it means you are trying to do something with this uninitialized variable, which without war3err causes a thread crash. You should initialize your variable with a null value.

Also, uninitialized variables have nothing to do with leaks, I don't know where you got the correlation.
09-08-2007, 06:12 PM#12
darkwulfv
All I'm trying to do to the variables is null them at the end. Bah. If they don't get set to anything (thus uninitialized) because they get set inside an If/then (and the if returns false), all I'm doing to them is nulling them. But if it causes a thread crash, that would probably mean the remaining variables that need to be nulled would not be.

Setting the variable to null when it's called ('local thing x = null') will fix this, correct?
09-08-2007, 06:24 PM#13
Captain Griffen
...setting a non-initiated variable won't cause a thread crash. If it did, no variable could ever be set...
09-08-2007, 06:52 PM#14
Anitarf
What we're saying is that if War3err reported an uninitialized variable use then you most likely tried to do something more with it than just set it. We can't know for sure because you haven't posted the whole function.

But yes, giving an initial null value to it would avoid all danger of uninitialized variable use.
09-08-2007, 07:00 PM#15
PipeDream
Try the new grimoire. If your function is largely driven by its arguments, the uninitialized var use will throw a stack trace showing what data caused it to fail. If the data comes from globals or callback functions, you can use the debugger to step to the failure point and find out exactly where it goes wrong.