Hi Paul,
I think if you did "attr regex_t" in debug, you'd see that it is indeed
644 bytes long. However, I think you're assuming that the size of your
data structure will always be the same as the distance between one
element of myds and the next -- and that's not the case.
myds has two elements, each one is 644 bytes long. However, they're
stored 656 bytes apart in memory.
This is required in order for the alignment to match on every occurrence
of the data structure. Pointers on i5/OS must always (*always*, even if
you don't specify ALIGN) be aligned at 16-byte intervals.
For the first element of your myds, the re_comp pointer will (again,
regardless of the aLIGN keyword) be at offset 16 from the start of the
structure. It can't be at offset 4 because that wouldn't be aligned at
16 byte intervals.
Now consider the second element of myds. You wonder why it's aligned at
656? Well, if it were starting at offset 644, (and therefore, re_nsub
would occupy offset 644-647) then re_comp would be located at offset
656, since it's the next 16-byte boundary after 648. The problem is
that 656 is 12 bytes from the start of myds(2), whereas in the FIRST
element of myds, re_comp was 16 bytes from myds(1). That's why myds(2)
actually starts at offset 656, because if it didn't, the pointers
couldn't be located at the same offsets as they were in the first
element of the array.
Basically, each array element (assuming that it contains pointers) must
always start at a 16-byte boundary in order to preserve the same offsets
that the subfields had in the first element.
So, yes.. each data structure is 644 bytes long. If you only plan to
allocate one copy in memory, it's perfectly safe to allocate 644 bytes
of memory.
However, if you want to create an array and put them in consecutive
locations in memory, then each element of the array must be 16-byte
aligned, and therefore, the total size of your array must be allocated
at 656 times the number of array elements.
Note that none of this is related to the ALIGN keyword. in fact, I
think (if I looked closely enough) that you could remove the ALIGN
keyword and it'd make no difference at all. ALIGN is just for aligning
integers (10i 0, 10u0 , 5i 0, 5u 0) on 4 or 2 byte boundaries, but I
think everything in your DS is already aligned that way without the
ALIGN keyword.
Paul Jackson wrote:
Hello,
I have a DS array (myds) (below) that is aligned and also which I will
be assigning storage to dynamically. In RPG IV the %size function
indicates that each entry is 644 bytes long (also indicated on the
compile listing), but if I do an "attr myds" in debug is says the size
is 41984 which when divided by the number of elements (64) gives an
element size of 656 which matches a 16 byte aligned structure.
I am concerned that if I use the %size value when allocating storage
that I am not giving sufficient space to the structure which could
cause issues with corrupted memory. Should I be allocating 656 to
each element of myds or 644?
Thanks for any comments on this question.
-Paul
D myds ds likeds(regex_t)
D dim(64)
D based(pMyds)
D regex_t DS qualified
D align based(prototype_only)
D re_nsub Like(size_t)
D re_comp *
D re_cflags 10I 0
D re_erroff Like(size_t)
D re_len Like(size_t)
D re_ucoll Like(LC_COLVAL_T) dim(2)
D re_lsub *
D lsub_ar Like(size_t) Dim(16)
D esub_ar Like(size_t) Dim(16)
D reserved1 *
D re_esub *
D re_specchar *
D re_phdl *
D comp_spc 1A Dim(112)
D re_map 1A Dim(256)
D re_shift Like(mbstate_t)
D re_dbcs 5I 0
D size_t S 10U 0
D LC_COLVAL_T S 10I 0
D mbstate_t S 5I 0
As an Amazon Associate we earn from qualifying purchases.