× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Hi Kim,

"type_ds" is a variable that's internal to a subprocedure. That means that your program requests memory for type_ds when the procedure starts, and tells i5/OS that it can have the memory back (for re-use) when the procedure ends.

Since you use pointers to refer to the data after the procedure has ended, it'll be a matter of luck as to whether i5/OS has re-used the memory for something else, or not. If it has, you'll get "garbage" in it. (It's not really garbage, the memory is just being used for something else, so it has values you didn't expect.) If you change it, then whatever else is using the memory (most likely, one of your other procedures) will see "garbage" in some of it's variables, because it's not expecting you to overwrite the data with something else.

The quick-fix, band-aid for this is to code "static" on the D-spec for the "type_ds" data structure. The keyword "static" means that the memory is NOT released when the procedure ends, instead it's retained until the activation group ends. It also means that any INZ statements are only carried out once -- when the subprocedure is called the first time -- and not re-run each time the procedure is called. The static DS will retain it's values between calls to the procedure.

However, frankly, this is not a good way to write code. What you SHOULD do is:

a) Eliminate the pointer logic.
b) Eliminate the fact that the format of the data structure is defined in multiple places (which is error prone, and maintenance heavy)
c) Have a higher-level caller be responsible for the memory instead of the subprocedure, which makes it more re-usable. (If you have multiple callers, they don't overwrite each other's values.)

These things may sound a little complex, but really they're not.. not at all... Just pass the data structure as a PARAMETER (without CONST or VALUE) instead of returning a pointer. Declare your parameters and variables using LIKEDS so that the format of the DS only needs to be declared once. It's easy.



Kim Spears wrote:
To fellow ILEers

I'm trying to use a pointer to a data structure to pass data back from a
sub procedure. I had it working at one point but have since made some
changes and now it doesn't work. What's happening is $obcGetType loads
the data structure properly and the pointer is getting passed back to
$obcSelect, however the data in the 'type' data structure in $obSelect
is garbage. It's almost like once $obcGetType goes out of scope the
memory for type_ds gets corrupted. Any suggestions?

D $obcGetType PR *
D obcFile 10 CONST
D obcField 10 CONST
****************************************************************
* $obcSelect - Prompt for valid one-byte codes for a specified
* field in a specific file
*--------------------------------------------------------------*
P $obcSelect B EXPORT
D $obcSelect PI 1
D obcFile 10 CONST
D obcField 10 CONST

D p_type S *
D type DS BASED(p_type) Qualified
D ID 10I 0
D Description 50A
*--------------------------------------------------------------*
C EVAL p_type = $obcGetType(obcFile :
obcField)
.
.
.
C RETURN oneByteCode
*--------------------------------------------------------------*
P $obcSelect E
****************************************************************
* $obcGetType - Given a file and field return the type
*--------------------------------------------------------------*
P $obcGetType B
D $obcGetType PI *
D obcFile 10 CONST
D obcField 10 CONST

D p_type S *
D type S BASED(P_TYPE) LIKE(type_ds)

D type_ds DS Qualified
D ID 10I 0
D Descrptn 50A
*--------------------------------------------------------------*
/FREE

OPEN DOOBCTYP01;
CHAIN (obcFile:obcField) DOOBCTYP01;
IF %FOUND(DOOBCTYP01);
EVAL type_ds.ID = otID;
EVAL type_ds.Descrptn = otDescrptn;
EVAL p_type = %ADDR(type_ds);
ELSE;
EVAL p_type = *NULL;
ENDIF;
CLOSE DOOBCTYP01;
RETURN p_type;

/END-FREE
*--------------------------------------------------------------*
P $obcGetType E



As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.