Dynamically allocating a data area does not allocate enough memory. (Visual Cobol 6.0)

Hi,

I am trying to allocate only the needed amount of memory when working with static tables in cobol. The table(which is part of a data-area) is then used as a parameter in json generate statement.

Suppose there are two programs. Program TestA and TestB. TestA calls TestB which is the one responsible to allocate n amount of memory depending on the size of the table. This means that even though the table has a boundary of 50000 items I want that the amount of byte allocated to the data-area should be less than that(depending on the amount of items populated which is known only in runtime).
Below is the an example:

program-id. TestA as "TestA"
environment division.

configuration section.

data division.
working-storage section.

01 foo-pointer.
04 tmp-ptr pointer.
1 tbl-size pic 9(8) value 0.
1 outputarea pic x(53400356) value space.

linkage section.
1 fooArea.
2 fooResponse.
3 fooRespOkPayload.
4 fooRespOkCode pic x(10) value space.
4 fooRespOkMessage pic x(100) value space.
4 fooRespObject.
5 fooRespObjectName pic x(50).
5 fooRespList occurs 50000 depending on tbl-size.
6 fooRespObjectOwnership pic x(40) value
space.
3 fooRespFailPayload.
4 fooRespFailCode pic 9(6) value 0.
4 fooRespFailMessage pic x(100) value space.
$set sourceformat "fixed"

procedure division.

call "TestB" using fooArea foo-pointer tbl-size

set address of fooArea to tmp-ptr
if tmp-ptr = null
display "Null"
stop run
end-if

json generate outputarea from fooArea
on exception
display
"Error generating json using dynamic allocation"
end-json
display outputarea
free tmp-ptr
cancel "TestB"
goback

end program TestA.

copy "cblproto".
program-id. TestB as "TestB".

environment division.
configuration section.

data division.
working-storage section.
1 x pic 9(8).
1 totalLengthOfFoo pic 9(15) value 0.
1 lgnthOfSingleItem pic 9(15) value 0.
1 maxOccrTbl pic 9(8) value 0.
1 sizeOfOnlyTbl pic 9(8) value 0.
1 sizeOfSingleElem pic 9(8) value 0.
1 byteToAllocate pic 9(15) value 0.
1 remainderSizeOfInput pic 9(8) value 0.
1 realSizeOfSingleElem pic 9(8) value 0.
linkage section.
1 fooArea.
2 fooResponse.
3 fooRespOkPayload.
4 fooRespOkCode pic x(10) value space.
4 fooRespOkMessage pic x(100) value space.
4 fooRespObject.
5 fooRespObjectName pic x(50).
5 fooRespList occurs 50000 depending on tbl-size.
6 fooRespObjectOwnership pic x(40) value
space.
3 fooRespFailPayload.
4 fooRespFailCode pic 9(6) value 0.
4 fooRespFailMessage pic x(100) value space.
01 foo-pointer.
04 tmp-ptr pointer.
1 tbl-size pic 9(8) value 0.

procedure division using fooArea foo-pointer tbl-size.

display "TestB"
move 50000 to x tbl-size
move length of fooArea to totalLengthOfFoo
move length of fooRespList to lgnthOfSingleItem*> 40
display length of fooRespObject
display length of fooRespObjectName
compute maxOccrTbl = (length of fooRespObject -
function length(fooRespObjectName)) /
lgnthOfSingleItem
compute sizeOfSingleElem = totalLengthOfFoo / maxOccrTbl
compute sizeOfOnlyTbl = lgnthOfSingleItem * maxOccrTbl
compute remainderSizeOfInput =
totalLengthOfFoo - sizeOfOnlyTbl
move 2 to x

compute byteToAllocate = (sizeOfSingleElem * x +
remainderSizeOfInput)
allocate byteToAllocate characters
returning tmp-ptr

if tmp-ptr = null
display "Could not allocate mem"
end-if

set address of fooArea to tmp-ptr
initialize fooArea(1:byteToAllocate)

move "Workshop" to fooRespObjectName
move "Test1" to fooRespObjectOwnership(1)
move "Test2" to fooRespObjectOwnership(2)
move x to tbl-size
goback
end program TestB.

The result of the json generate can be seen below


I do believe that not enough data is allocated because when I try to assign a value to fooRespFailMessage after setting address of fooArea to tmp-ptr I get the 114 error code(Attempt to access item beyond bounds of memory).

Any help is appreciated.

Tags:

  • 0  

    Hi Orgi,

    I cannot run your test application as the call statement is passing parameters which are in the linkage section of TestA and they have no memory allocated to them before the call. I immediately get a 114 error. Is there another program that calls TestA?

    On what platform are you running and what compiler directives are in use? Do you use ODOSLIDE? This automatically resizes ODO tables according to the current value of the ODO item.

    Thanks

    Chris Glazier
    Rocket Software - Principal Technical Support Specialist
    If you found this post useful, give it a “Like” or click on "Verify Answer" under the "More" button

  • 0 in reply to   

    Hi Chris,
    That was interesting. There is no other program that calls TestA. I am running this right now on Visual Cobol Eclipse.

    On program level this seems to be the directives of TestA.


    Do you know how I can find the directives used when compiling on AIX? 
    No I am not using ODOSLIDE.

    Kind regards,

    Orgi 

  • 0   in reply to 

    You can find the directives used to compile a program by placing the $SET SETTINGS directive on for the program. The directives used will then appear in the .lst file.

    Chris Glazier
    Rocket Software - Principal Technical Support Specialist
    If you found this post useful, give it a “Like” or click on "Verify Answer" under the "More" button

  • Verified Answer

    +1   in reply to 

    It appears like in my test it was the length of outputarea that is causing the 114. If I reduce the size the program runs.

    without ODOSLIDE an ODO table is always assumed to be the maximum size allocated so you cannot allocate less memory for it.

    The following is from the docs for the occurs clause:

    If the NOODOSLIDE Compiler directive is set, all group items containing the table are considered as always having the maximum number of occurrences, irrespective of the value of data-name-1 and therefore the position of the data items following the table is not changed.

    Chris Glazier
    Rocket Software - Principal Technical Support Specialist
    If you found this post useful, give it a “Like” or click on "Verify Answer" under the "More" button

  • 0 in reply to   

    Okay, setting the ODOSLIDE compiler directive(both on TestA and TestB) seem to fix it. Now it only allocates the minimum amount of memory(I suppose there is a bare minimum of memory allocated no matter how small the size of data-area(in my case only around 360 byte) is? Looping through the table until the index > 50000 makes it crash around element 197(error 114). Thank you for your help. :) 

  • 0   in reply to 

    When the program crashes while looping through table until the index > 50000, what is the ODO item set to? You should never reference an item in an ODO table that is outside the range specified by the value of the current ODO item..

    Chris Glazier
    Rocket Software - Principal Technical Support Specialist
    If you found this post useful, give it a “Like” or click on "Verify Answer" under the "More" button