WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Arrays
plus
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

ArrayRedim Issue

 Keywords:  ArrayRedim UDF UDF User Defined Function Binary Buffer Corrupted Array Global Pointer PtrGlobalDefine ptrGlobal

Question:

When the following code is run, data inside some of the binary buffers becomes corrupted.
ARR=ArrDimension(1)

BUFFER=BinaryAlloc(480000)

#DefineFunction ARRAYREDIM_WORKAROUND(ARR,DIM1,DIM2,DIM3,DIM4,DIM5)
   ArrayRedim(ARR,DIM1,DIM2,DIM3,DIM4,DIM5)
#EndFunction

#DefineFunction TEST(ARR)
   INDEX=ArrInfo(ARR,1)
   ArrayRedim(ARR,INDEX+1,-1,-1,-1,-1)
;   ARRAYREDIM_WORKAROUND(ARR,INDEX+1,-1,-1,-1,-1)
   BIN=BinaryAlloc(32)
   BinaryPokeStr(BIN,0,"THIS IS A TEST STRING.")
   ARR[INDEX]=BIN
#EndFunction

TEST(ARR)
TEST(ARR)
TEST(ARR)
TEST(ARR)

#DefineFunction PRINT_R(ARR)
   TEXT=""
   For X=0 To ArrInfo(ARR,1)-1
      If IsDefined(ARR[X]) Then TEXT=TEXT:X:" => [":BinaryPeekStr(ARR[X],0,32):"]":@CRLF
   Next
   Return TEXT
#EndFunction

Message("",PRINT_R(ARR))
However, if the ArrayRedim() function is placed inside of another function and called via the other function, the data corruption does not occur.

Answer:

I wasn't able to reproduce the problem directly using WinBatch 2013C, but was able to find a significant issue via other means. The problem has nothing directly to do with binary buffers and is the result of how the array reference change is being propagated during the return from the UDF call.

I would not count on the proposed workaround consistently working either. For now you should not use the ArrayRedim, ArrayRemove, or ArrayInsert functions inside UDF/S's on arrays passed as parameters to the UDF/S.

One safe workaround would be to define and access the array as a global pointer.

PtrGlobalDefine(arr)

#DefineSubRoutine TEST()
   parr = PtrGlobal(arr)

   INDEX=ArrInfo(*parr,1)
   ArrayRedim(*parr,INDEX+1,-1,-1,-1,-1)
   BIN=BinaryAlloc(32)
   BinaryPokeStr(BIN,0,"THIS IS A TEST STRING.")
   *parr[INDEX]=BIN
#EndFunction
We really appreciate users taking the time to report problems like this and we should have it fixed in the next release.

User Reply:

Would this be a safe workaround? I pass an array reference to the function and then dereference it inside the function.
ARR=ArrDimension(0)

#DefineFunction TEST(ARR)
   INDEX=ArrInfo(*ARR,1)
   ArrayRedim(*ARR,INDEX+1,-1,-1,-1,-1)
   BIN=BinaryAlloc(32)
   BinaryPokeStr(BIN,0,"THIS IS A TEST STRING.")
   *ARR[INDEX]=BIN
#EndFunction

TEST(&ARR)

Answer:

Excellent. Yes, that does work around the problem and is a cleaner solution than using a global pointer.
Article ID:   W17657
Filename:   ArrayRedim Issue.txt
File Created: 2013:09:20:08:41:06
Last Updated: 2013:09:20:08:41:06