Page 1 of 1 1
Topic Options
#207022 - 2013-04-02 08:55 AM Array reference out of bounds error
Danks Offline
Just in Town

Registered: 2013-03-27
Posts: 2
Loc: DK
Hello
I have the following problem. I am getting the following error "array refrence out of bounse" and I can not quite figure out the cause.
Does anyone has a suggestion on how to solve the problem.

The error occurs in the following code in the line( $Groups[$Count] = $Group - marked with red):

PS. I'm not a big KIX script guru ;-)


If (GetFileSize($ULTmpFile + ".iso8859") > 0)

$Err = Open(9,$ULTmpFile + ".iso8859")

$Readln = Readline(9)
While (@Error = 0)

If(InStr($Readln,"cn:"))
$Group = SubStr($Readln, 5,Len($Readln)-4)
; ?"$Group $Count" GET$

$Groups[$Count] = $Group
$Count = $Count + 1
EndIf
$Readln = Readline(9)
Loop

$ULCount = $Count - 1 ; Antallet af Grupper, startende ved 0
; ?"$UlCount"
$ULResult = 0
$Err = Close(9)
Else
$ULResult = 1
EndIf

Top
#207023 - 2013-04-02 12:21 PM Re: Array reference out of bounds error [Re: Danks]
BradV Offline
Seasoned Scripter
****

Registered: 2006-08-16
Posts: 686
Loc: Maryland, USA
Where do you set $Count initially? Also, you probably have to REDIM PRESERVE it each time you try to increase the size.
Top
#207024 - 2013-04-02 01:15 PM Re: Array reference out of bounds error [Re: BradV]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Welcome to KORG!

There are two common methods for working with arrays of unknown size. One is to set the size of the array to an excessively large value, like
Dim $aData[500]
when you know there will be less than 500 elements. A better way is to use ReDim, as Brad referenced..
 Code:
Dim $aData         ; declare array var, no size
Dim $Ptr           ; pointer var

$Ptr = -1          ; set to negative first

; Time to add an element to the array, possibly in a loop
$Line = ReadLine(9)
While Not @ERROR
  $Ptr = $Ptr + 1  ; increase pointer
  ; increase the array size to hold the new data
  ReDim Preserve $aData[$Ptr]
  ; put the data from the file in the array
  $aData[$Ptf] = $Line
  ; read the next data line
  ReadLine(9)
Loop
This method is much preferred as it accurately maintains the size of the array. Of course, you might add logic to this to only add certain lines of data to the array, but the basic concept is the same

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207027 - 2013-04-02 01:38 PM Re: Array reference out of bounds error [Re: Glenn Barnas]
Lonkero Administrator Offline
KiX Master Guru
*****

Registered: 2001-06-05
Posts: 22346
Loc: OK
oh, there is a third one:
 Code:
$Readln = Readline(9)
While @Error = 0
 If InStr($Readln,"cn:")
  $Group = SubStr($Readln, 5,Len($Readln)-4)
  $Groupster = $Groupster+chr(9)+$Group
 EndIf
 $Readln = Readline(9)
Loop
$groups=split(substr($groupster,2))
_________________________
!

download KiXnet

Top
#207056 - 2013-04-04 04:06 PM Re: Array reference out of bounds error [Re: Lonkero]
Danks Offline
Just in Town

Registered: 2013-03-27
Posts: 2
Loc: DK
Thank you for your response. It teased a bit because I did not originally written the code. ;-)
Found out that the size of the array was underestimated and overlooked that it was placed further up in code .....

Is there any reason why Gleen argue that an array must not exceed 500 I can see it's possibil to dimension a array higher .....?

Top
#207057 - 2013-04-04 04:24 PM Re: Array reference out of bounds error [Re: Danks]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
That was an example.. if you expect an array to hold LESS THAN 500 elements, you can Dim it to 500 and feel safe. It's a common method - overstate your required array size, but any unexpected condition can overload your array and cause an error.

Lonk's method is good for smaller arrays because you need to deal with potential string limits (especially in other languages!). It also can't accommodate Arrays of Arrays, although this is less common.

The second method that I illustrated is usually preferred because it can accommodate any data type in the array, and doesn't result in bound errors if your data exceeds your expectation.

Glenn (with 2 "N"'s and 1 "e"! \:D
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207058 - 2013-04-04 04:50 PM Re: Array reference out of bounds error [Re: Glenn Barnas]
Allen Administrator Online   shocked
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4545
Loc: USA
Ha... the return of Gleen. Where have you been my friend.
Top
#207059 - 2013-04-04 07:04 PM Re: Array reference out of bounds error [Re: Allen]
ChristopheM Offline
Hey THIS is FUN
*****

Registered: 2002-05-13
Posts: 309
Loc: STRASBOURG, France
I use an other solution to load file because resizing array at each line can be expensive in time and memory.
 Code:
function LoadArrayFromFile( $filename, optional $PtrMax, optional $PtrInc )
  if vartype($PtrMax)=0    $PtrMax = 1024   endif    ; initialize max size
  if vartype($PtrInc)=0    $PtrInc = 256    endif    ; initialize increment size

  dim $Ptr                 $Ptr = -1                 ; set pointer to negative first
  dim $handle              $handle = freefilehandle()

  if open( $handle, $filename )=0
    redim $LoadArrayFromFile[$PtrMax] ; declare array var with a predefined size
    dim $line

    ; Time to add an element to the array, possibly in a loop
    $Line = ReadLine($handle)
    While Not @ERROR
      $Ptr = $Ptr + 1                                ; increase pointer
      if $Ptr > $PtrMax
	    $PtrMax = $PtrMax + $PtrInc                  ; increase array max size
        ReDim Preserve $LoadArrayFromFile[$PtrMax]   ; resize array
      endif

      $LoadArrayFromFile[$Ptr] = $Line               ; put data in array
      $Line = ReadLine($handle)                      ; read the next data line
    Loop

    $ = close($handle)
  endif

  if $Ptr=-1
    ; nothing read in the file or file not opened
	$LoadArrayFromFile = ""
	exit 1
  else
    ReDim Preserve $LoadArrayFromFile[$Ptr]
	exit 0
  endif
endfunction
This is a function that allows to define initial size of the array and increment size when array becomes too small to load next data.

See below how to test with differents sizes of buffer and increment
 Code:
$=SetOption( "Explicit", "ON" )

dim $filename, $arr, $start

$filename = "<name of a large file for test>"

$start=@TICKS
$arr = LoadArrayFromFile( $filename, 0, 1 )
$start=@TICKS-$start
"Loaded line by line (   0,   1) in " $start " ms" ?

$start=@TICKS
$arr = LoadArrayFromFile( $filename )
$start=@TICKS-$start
"Loaded with default (1024, 512) in " $start " ms" ?

$start=@TICKS
$arr = LoadArrayFromFile( $filename, 4096, 4096 )
$start=@TICKS-$start
"Loaded with buffer  (4096,4096) in " $start " ms" ?


with a file of 32000 lines (1,1MB), here are the results :
 Code:
Loaded line by line (    0,   1) in 469 ms
Loaded with default ( 1024, 512) in 312 ms
Loaded with default ( 4096,4096) in 297 ms
_________________________
Christophe

Top
#207060 - 2013-04-04 07:23 PM Re: Array reference out of bounds error [Re: ChristopheM]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
LOL - I was going to mention this concept to improve performance but decided it was too complex for this discussion. So - there it is - nicely done! \:\)
_________________________
Actually I am a Rocket Scientist! \:D

Top
#207109 - 2013-04-15 09:43 PM Re: Array reference out of bounds error [Re: Glenn Barnas]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Just to follow-up on this, I revisited the FileIO UDF that I had written some time ago. I found that I had used Lonk's "build a delimited string and split" method. I had been planning on updating it to use a stepped-dynamic array method and finally got around to it today.

To compare the performance of the old and new methods, I created a simple text file of about 380KB, with just under 5000 lines. The old "build & split" method took 28.157 seconds to load this file into the array and resulted in an array with an extra, empty element. Using the newer "Stepped-dynamic" method that Christophe illustrated above (with a base/increment of 500 elements), loading the same file took a whopping 0.125 seconds (yes, an eighth of a second!).

Bottom line, I should have updated the UDF to this method years ago!

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
Page 1 of 1 1


Moderator:  Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart 
Hop to:
Shout Box

Who's Online
1 registered (Allen) and 466 anonymous users online.
Newest Members
gespanntleuchten, DaveatAdvanced, Paulo_Alves, UsTaaa, xxJJxx
17864 Registered Users

Generated in 0.042 seconds in which 0.016 seconds were spent on a total of 13 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org