I'm getting strange results when attempting to de-allocate a static based variable. Below is a small test program I've created to demo the issue I'm having. The static based variable is in the proc1 sub-procedure of this test program. Its name is myIx, with based pointer of myIx_p. I put comments in the main body of the program to indicate the issues that I'm having. What am doing wrong here?
D ix s 5i 0
/free
ix = proc1(*off); // ix is 1 after this statement => Expected
ix = proc1(*off); // ix is 2 after this statement => Expected.
ix = proc1(*on); // ix is 0, which is expected. But myIx_p is not being set to null => NOT Expected
ix = proc1(*off); // ix is 3 after this statement => NOT Expected. Expecting 1.
ix = proc1(*on); // try to shutdown again and get CEE0810 error => NOT Expected
*inlr = *on;
*------------------------------------------------------------------------------------------
* proc1 to test based static variable
*------------------------------------------------------------------------------------------
P proc1 B
D pi 5i 0
D piShutDown n const
D myIx s 5i 0 based(myIx_p)
D myIx_p s * static
// caller only wants to shutdown the proc
if (piShutDown and myIx_p <> *null);
dealloc myIx_p;
return 0;
endif;
// allocate myIx if not yet allocated
if (myIx_p = *null);
myIx_p = %alloc(%size(myIx));
endif;
// increase the value by 1 as a test
myIx += 1;
return myIx;
P E
/end-free
The answer is right there in your comments. You do not set myIx_p = *null
after you dealloc
. Failure to set it to *null
means it is still pointing to the same memory location that it was only the operating system no longer sees it as allocated. The behavior you are seeing is entirely expected. The fix is as simple as:
// caller only wants to shutdown the proc
if (piShutDown and myIx_p <> *null);
dealloc myIx_p;
myIx_p = *null;
return 0;
endif;
You can also resolve it as thus according to the IBMi documentation:
// caller only wants to shutdown the proc
if (piShutDown and myIx_p <> *null);
dealloc(n) myIx_p;
return 0;
endif;
If you don't use (n), you must set it to *null yourself like in the first example. See the documentation about dealloc
here: https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/rzasd/zzdeall.htm