The need to dispose

Guys, I need clarification about disposing a variable.

  1. Can you dispose(var) without “damage” even if perhaps it does not need disposing?
  2. Code like this:
 hr = NewIFormX.CreateInstance()
        if hr ~= S_OK_PW            
            lCOMErrorlen = size(szCOMError)
            if COMError.GetError(szCOMError, lCOMErrorlen, hr) !~= ERR_SUCCESS
                szCOMError = 'Unknown error: hr = '&hr
            end
            NewIFormX.Release() 
        ELSE        
            clear(pbstrparam)
            sz &= NewIFormX.getVoziloSteza(p:szAMRVLVoziloId,P:szANalepkaTip, P:szANalepka, p:szAPDTip, p:szAPD, p:szAVIN, p:szAVINT, p:szARTTip, p:sz_ART, p:szAPSOznaka, p:szAPS, p:szAZTP, hr)    
            if hr = S_OK_PW and ~sz &= null
                szADataReturnText = sz            
                dispose(sz)
            else
                lCOMErrorlen = size(szCOMError)
                if COMError.GetError(szCOMError, lCOMErrorlen, hr) !~= ERR_SUCCESS
                    szCOMError = 'Unknown error: hr = '&hr
                end            
            ! ********** Do I need dispose here?"
            end        
            NewIFormX.Release() 
        end

It’s initiating a COM instance and doing a call to some dll. Notice the “! do I need dispose here?”

So is there a rule that whenever you have:

someVar &=

you must automatically do

dispose(someVar)

later on after you “use” its contents? Or does it matter if perhaps someVar is Null?

I’m asking because I rarely code myself things like this but in this particular case I have, I’m getting some GPFs occasionally so I reckon this might be the problem.

Cheers

No. If memory pointed by the value of the reference variable using as a parameter of DISPOSE, this either cause run-time error or memory corruption. If parameter points to a memory block that has not been allocated by previous NEW, DISPOSE causes run-time error.

If NewIFormX.getVoziloSteza returns not-NULL reference even if hr is not S_OK_PW, DISPOSE is required.

There is no such rule. For example,

V LONG
Ref &LONG

Ref &= V

Ref is not required to be DISPOSEd. Another example:

S &STRING
Ref1 &STRING
Ref2 &STRING

S &= NEW STRING(100)
Ref1 &= S
Ref2 &= S

Only one variable S, Ref1 or Ref2 must be DISPOSEd in this example because all 3 are pointing to the same memory.

Hmmm. I might state something stupid now but I’ll still give it a try.

So, if some var is referenced to a var which has has been defined (like V LONG) thru compiler, then we don’t need to dispose it because it has a memory block reserved in anycase (which we cannot free at all) as long as the app is running.
But if we create a variable (“NEW it”) at runtime, we therefore reserve some memory block with it and we need to dispose it to free the memory because the app sort of has no idea we made a new variable block somewhere in the memory?

Is that correct? If yes, am I - by calling sz &= NewIFormX… - actually creating some reservation of a memory block and referencing sz to it? So when I dispose(sz), I free that block? And if I dispose(sz) when sz = null, I’m freeing something that does not really exist which is why I could get gpf?

Yes, but if the reference to NEWed data has been assigned to several reference variable, only one of them must be DISPOSEd, If the program is DISPOSEing a QUEUE and its record has fields of a reference type or of ANY type, it can be required to enumerate queue’s record to free referenced data.

You must know better that this function is doing.

If NewIFormX… is allocating a data object, yes, DISPOSE(sz) is required to free it and to invoke that object’s destructor before freeing.

DISPOSE checks that passed reference value is not NULL. If it is NULL, DISPOSE does nothing.