|
|
|||||||
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 |
||||||||
|
|
|||||||
Where do you set $Count initially? Also, you probably have to REDIM PRESERVE it each time you try to increase the size. |
||||||||
|
|
|||||||
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 Glenn |
||||||||
|
|
|||||||
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)) |
||||||||
|
|
|||||||
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 .....? |
||||||||
|
|
|||||||
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"! |
||||||||
|
|
|||||||
Ha... the return of Gleen. Where have you been my friend. |
||||||||
|
|
|||||||
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 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 |
||||||||
|
|
|||||||
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! |
||||||||
|
|
|||||||
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 |