Kbase P142118: 4GL/ABL: SET-SIZE() = 0 fails to set the size of a MEMPTR variable to zero in a class METHOD.
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  1/25/2010 |
|
Status: Verified
SYMPTOM(s):
4GL/ABL: SET-SIZE() = 0 fails to set the size of a MEMPTR variable to zero in a class METHOD.
SET-SIZE() = 0 fails if a previous call to the class METHOD sets the MEMPTR variable size to a non zero value.
In the following code samples, the MemptrTestCaller.p procedure invokes the loadData() METHOD of the MemptrTest.cls class multiple times, the last call to the loadData() METHOD fails to set the MEMPTR size to 0 as expected:
/* MemptrTestCaller.p */
DEFINE VARIABLE iCounter AS INTEGER NO-UNDO.
DEFINE VARIABLE mData AS MEMPTR NO-UNDO.
DEFINE VARIABLE memptrTest AS MemptrTest NO-UNDO.
memptrTest = NEW MemptrTest().
DO iCounter = 10 TO 0 BY -5:
mData = memptrTest:loadData(iCounter).
MESSAGE
"Counter:~t" iCounter "~n"
"Size:~t" GET-SIZE(mData)
VIEW-AS ALERT-BOX.
END.
DELETE OBJECT memptrTest.
/* MemptrTest.cls */
USING Progress.Lang.*.
CLASS MemptrTest:
METHOD PUBLIC MEMPTR loadData (piSize AS INTEGER):
DEFINE VARIABLE mData AS MEMPTR NO-UNDO.
SET-SIZE(mData) = piSize.
RETURN mData.
END METHOD.
END CLASS.
When running the MemptrTestCaller.p procedure, the last iteration displays the MEMPTR size as 5, the value set in the previous call, and not 0 as expected to have been set in the last iteration when the iCounter = 0.
FACT(s) (Environment):
All Supported Operating Systems
OpenEdge 10.2A
CAUSE:
Bug# OE00181699
CAUSE:
Prior to 10.2A, a function/method returning a memptr did not returned a copy of the memptr. That means that the caller gets the memptr allocated in the called procedure, and when you call that function/method again, you are still looking at the same memptr so that's why you see that the memptr does not get resized by set-size(). You would have to set-size(0) before trying to resize it.
Now in 10.2A, we changed how memptr return values are handled and we now do make a copy, and we attempt to reset the called's memptr so that is in uninitialized. However, there is a bug where we do not reset the memptr's size, so when you try to resize it to 0 it won't work because we notice that the memptr is supposedly not initialized and ignore set-size(0) - that's why get-size reports the old size even though the memptr's pointer is zero.
FIX:
Upgrade to OpenEdge 10.2B or later.
If upgrading to OpenEdge 10.2B or later is not feasible, then a workaround is to set the size of the MEMPTR variable in the called METHOD to a nonzero value, then to 0 and finally to the intended value. For example:
/* MemptrTest.cls */
USING Progress.Lang.*.
CLASS MemptrTest:
METHOD PUBLIC MEMPTR loadData (piSize AS INTEGER):
DEFINE VARIABLE mData AS MEMPTR NO-UNDO.
/* The following two lines are the workaround */
SET-SIZE(mData) = 1.
SET-SIZE(mData) = 0.
/* The above two lines are the workaround */
SET-SIZE(mData) = piSize.
RETURN mData.
END METHOD.
END CLASS.