• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] Leaks and Nulling Questions

Status
Not open for further replies.
Level 17
Joined
Feb 11, 2011
Messages
1,860
Hi guys,

I have two burning questions that I want to get out of the way. Here they are;

Question 1:
If I have a small function that returns a damage amount based on a hero's strength like this:

JASS:
private function GetDamage takes unit u returns real
    return 6. * GetHeroStr(u, true)
endfunction

How necessary is it to null the unit variable? It seems as though it would make the function longer:

JASS:
private function GetDamage takes unit u returns real
    local real str = GetHeroStr(u, true)
    set u = null
    return 6. * str
endfunction

Question 2:
When destroying struct instances, is it necessary to set each variable with a handle to null before deallocating? For example:

JASS:
private struct Test
    unit caster
    unit target
    
    private method destroy takes nothing returns nothing
        set .caster = null
        set .target = null
        call .deallocate()
    endmethod

    private method kill takes nothing returns nothing
        call KillUnit(.caster)
        call KillUnit(.target)
        call .destroy()
    endmethod
    
    private static method create takes nothing returns thistype
        local thistype this = thistype.allocate()
        
        set .caster = GetTriggerUnit()
        set .target = GetSpellTargetUnit()
        call .kill()
        
        return this
    endmethod

endstruct

I have always been doing this, but I am curious if .deallocate() is enough.

Thanks,

Mr_Bean
 
You don't have to do either. We only need to null local variables. Why?

Local variables act as pointers to certain objects. When destroying an object, if a local variable is still pointing it, then its handle ID will not be recycled. (considered a bug) However, if you make the local variable pointing it point to null instead, then the handle ID will be recycled properly.

That only is true for locals, though. So in this example:
JASS:
function Blah takes unit u returns nothing
    set u = GetTriggerUnit()
endfunction

You don't need to set u to null since the parameter variables behave differently.

Same thing with structs. All struct members are actually global arrays. For objects being destroyed, the handle id will be recycled even if a global is still pointing to it. That's why it is not necessary to null the globals.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Same thing with structs. All struct members are actually global arrays. For objects being destroyed, the handle id will be recycled even if a global is still pointing to it. That's why it is not necessary to null the globals.

Not really, it all depends how the struct is used.
But yeah in most of cases most of struct instances should be recycled soon or late.

To be accurate there is really minor memory leak (not an handle id one) if you don't null a global variable right after destroying the handle, but you don't really have to care about it, as long the variable will be used again later.
 
Well, ofc. :p But it would be kinda pointless to null just for the sake of saving that little bit of memory which will usually exist again anyway. (once the global gets reassigned) That is why some people null them. However, when it comes to micro-memory vs. nanoseconds/bits (time/file size) I choose the latter since it has nicer code and less work.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Well, ofc. :p But it would be kinda pointless to null just for the sake of saving that little bit of memory which will usually exist again anyway. (once the global gets reassigned) That is why some people null them. However, when it comes to micro-memory vs. nanoseconds/bits (time/file size) I choose the latter since it has nicer code and less work.


Actually, i'm talking about this
Yeah it's kinda irrevelant, but that's a memory leak, no more, no less, it will never be free even when the global variable will be used once time again.
 
Ah I completely forgot about that. Not sure why it didn't really catch on.

It is still of not much concern, (as stated in the thread) but I suppose it is something to consider if one really wants to avoid leaking memory. xD

P.S. Your memory is uncanny. :D

@Mr_Bean: I suppose it is your choice. vJASS standards/approvals don't really require struct nulling, but if you care about each bit of memory then it is not something bad to do. It is just about whether you prioritize memory or file size/work. (even though both are very insignificant in this case)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
The problem with structs is that you can't always be sure that all instances will be re-used soon or late, or if handle members will be destroyed or not during the game.

As an example you could reach a max instances of 100 at some point during the game, but then use no more than 10 of them.
If you have 90 differents handles stored in these struct instances and they are likely to be destroyed later during the game, you will have 90 handle id leaks.
Now, that's probably an unrealistic scenario, but this + this + this ...
That's why i always null struct members on instance destroy.
 
Status
Not open for further replies.
Top