Jump to content

Array bounds error


Recommended Posts

It's difficult to narrow this down to an example that you can run, so sorry about that, I'll try to break it down further if the problem isn't obvious from this. Here are the lines that are failing:

MsgBox(0,"Boxes","UBound="&UBound($Boxes)&@CRLF&"ProjNum="&$ProjNum&@CRLF&"UBound="&UBound($Boxes[$ProjNum]))
    GUICtrlSetState( $Boxes[$ProjNum][1], $GUI_CHECKED )

The message box says this:

post-22414-12687424066021_thumb.png

The script then fails with this error:

C:\dev\AutoIt\DSLaunch\DSLaunch2.au3 (397) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

Line 397 is the GUICtrlSetState call.

So, $Boxes has 1 element, $Boxes[0] has 4 elements, but $Boxes[0][1] is causing a failure. I don't understand.

Link to comment
Share on other sites

When you're at a loss, use the last resort magic wand:

Local $x[2] = [1.234, True]
Local $boxes[1][4] = [['abc', 75, $x, default]]
ConsoleWrite(_VarDump($boxes) & @LF)

Func _VarDump(ByRef $vVar, $sIndent = '')
    Select
    Case IsDllStruct($vVar)
    Return 'Struct(' & DllStructGetSize($vVar) & ') = ' & Hex($vVar)
    Case IsArray($vVar)
            Local $iSubscripts = UBound($vVar, 0)
            Local $sDims = 'Array'
            $iSubscripts -= 1
            For $i = 0 To $iSubscripts
                $sDims &= '[' & UBound($vVar, $i + 1) & ']'
            Next
    Return $sDims & @CRLF & _VarDumpArray($vVar, $sIndent)
    Case IsBinary($vVar)
    Return 'Binary(' & BinaryLen($vVar) & ')'
    Case IsBool($vVar)
    Return 'Boolean(' & $vVar & ')'
    Case IsFloat($vVar)
    Return 'Float(' & $vVar & ')'
    Case IsHWnd($vVar)
    Return 'HWnd(' & $vVar & ')'
    Case IsInt($vVar)
    Return 'Integer(' & $vVar & ')'
    Case IsKeyword($vVar)
    Return 'Keyword(' & $vVar & ')'
    Case IsPtr($vVar)
    Return 'Pointer(' & $vVar & ')'
    Case IsObj($vVar)
    Return 'Object(' & ObjName($vVar) & ')'
    Case IsString($vVar)
    Return 'String(' & StringLen($vVar) & ") '" & $vVar & "'"
    Case Else
    Return 'Unknown(' & $vVar & ')'
    EndSelect
EndFunc

Func _VarDumpArray(ByRef $aArray, $sIndent = '')
    Local $sDump
    Local $sArrayFetch, $sArrayRead, $bDone
    Local $iSubscripts = UBound($aArray, 0)
    Local $aUBounds[$iSubscripts]
    Local $aCounts[$iSubscripts]
    $iSubscripts -= 1
    For $i = 0 To $iSubscripts
    $aUBounds[$i] = UBound($aArray, $i + 1) - 1
    $aCounts[$i] = 0
    Next
    $sIndent &= @TAB
    While 1
    $bDone = True
    $sArrayFetch = ''
    For $i = 0 To $iSubscripts
    $sArrayFetch &= '[' & $aCounts[$i] & ']'
    If $aCounts[$i] < $aUBounds[$i] Then $bDone = False
    Next
    $sArrayRead = Execute('$aArray' & $sArrayFetch)
    If @error Then
    ExitLoop
    Else
    $sDump &= $sIndent & $sArrayFetch & ' => ' & _VarDump($sArrayRead, $sIndent)
    If Not $bDone Then
    $sDump &= @CRLF
    Else
    Return $sDump
    EndIf
    EndIf
    For $i = $iSubscripts To 0 Step -1
    $aCounts[$i] += 1
    If $aCounts[$i] > $aUBounds[$i] Then
    $aCounts[$i] = 0
    Else
    ExitLoop
    EndIf
    Next
    WEnd
EndFunc

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

PhilHibbs,

If you have ever done some more advanced maths you will probably have done something with matrices. For most arrays (1D and 2D) you can visualize them in much the same way.

For example:

Lets create $array[5] = [1, 2, 3, 4, 5] ; 1 row, 5 cols

Which can be displayed like a matrix as:

$array = [1 2 3 4 5]

If we create a 2D array-

$array[2][5] = [[1,2,3,4,5],[6,7,8,9,0]]; 2 rows, 5 cols

We get this (I split it up so it had a hope of displaying correctly. It probably didn't though):

$array =

| 1 2 3 4 5 |

| 6 7 8 9 0 |

If you think of it that way, whats the issue?

You've created a 1 dimension array, but you're trying to get the value of a 2D array...

I do believe the issue is with your UBound statement though. Probably the reverse of what I just said... 1D instead of 2D, but in ubound you just need to tell it the var name...

:(

Edited by BrettF
Link to comment
Share on other sites

Neat, but I still don't understand:

ConsoleWrite(_VarDump($ProjNum) & @LF)
    ConsoleWrite(_VarDump($boxes) & @LF)
    GUICtrlSetState( $Boxes[$ProjNum][1], $GUI_CHECKED )

>Running:(3.3.6.0):C:\Program Files\AutoIt3\autoit3.exe "C:\dev\AutoIt\DSLaunch\DSLaunch2.au3"    
Integer(0)
Array[1]
    [0] => Array[4]
        [0] => Integer(31)
        [1] => Integer(32)
        [2] => Integer(33)
        [3] => Integer(34)
C:\dev\AutoIt\DSLaunch\DSLaunch2.au3 (398) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
GUICtrlSetState( $Boxes[$ProjNum][1], $GUI_CHECKED )
GUICtrlSetState( ^ ERROR

@BrettF: The array should be 2-dimensional, although it was built dynamically and not explicitly dimensioned. Does an array have to be explicitly dimensioned as 2-dimensional in order for the [][] syntax to work?

Edited by PhilHibbs
Link to comment
Share on other sites

What do you mean by "not explicitely dimensionned" ?

Yes, of course, you have to explicitely give as many dimensions ([n] pairs) as you whish to your array. How could AutoIt (or any language) read your mind?

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

What do you mean by "not explicitely dimensionned" ?

Yes, of course, you have to explicitely give as many dimensions ([n] pairs) as you whish to your array. How could AutoIt (or any language) read your mind?

If you're switching between using 2 and 1 dimensions on the same array then your code is pointless and you make it hard for yourself...

Use one or two dimensions and not both.

AutoIt can know the number of dimensions in an array Ubound($array,0), but doing this way is pretty pointless.

Edited by BrettF
Link to comment
Share on other sites

What do you mean by "not explicitely dimensionned" ?

Yes, of course, you have to explicitely give as many dimensions ([n] pairs) as you whish to your array. How could AutoIt (or any language) read your mind?

By being dynamically typed? So, how would you address an element of the nested array in the following example from the help file:

$

$Array[0]=1
$Array[1]=true
$Array[2]="Text"
$Array[3]=$AnotherArray

It seems that the syntax $Array[3][0] is not valid in this case, which is the problem that I am having. Perhaps _ArrayAdd needs to handle adding an array to a multi-dimensional array differently. Bingo, that's it, _ArrayAdd doesn't do multi-dimensional arrays at all.

Link to comment
Share on other sites

OK, I've solved my problem - I initially DIM the array to be [1][4], and I will live with the fact that there will always be an empty, dummy zeroth entry in the array. I use this variant of _ArrayAdd, and all my loops run from 1 to UBound($array) instead of from 0, and when I delete entries I always stop before the last dummy entry is gone. _ArrayDelete already handles 2-dimensional arrays.

Func MyArrayAdd2(ByRef $avArray, $avValue)
    If Not IsArray($avArray) Then Return SetError(1, 0, -1)
    If UBound($avArray, 0) <> 2 Then Return SetError(2, 0, -1)

    Local $iUBound1 = UBound($avArray)
    Local $iUBound2 = UBound($avValue)
    ReDim $avArray[$iUBound1 + 1][$iUBound2]
    For $i = 0 To $iUBound2 - 1
        $avArray[$iUBound1][$i] = $avValue[$i]
    Next
    Return $iUBound1
EndFunc   ;==>_ArrayAdd
Link to comment
Share on other sites

By being dynamically typed? So, how would you address an element of the nested array in the following example from the help file:

This are possibilities:

Local $x[2] = [1.234, True]
Local $boxes[1][4] = [['abc', 75, $x, default]]
ConsoleWrite(_VarDump($boxes) & @LF)

; "array in array" isn't a very good idea
;
; using an intermediate variable
Local $y = $boxes[0][2]
ConsoleWrite($y[0] & @LF)

; another way: using a function
ConsoleWrite(_ArrayInArrayRead($boxes[0][2], 0) & @LF)

Func _ArrayInArrayRead(ByRef $ar, $idx)
    Return $ar[$idx] + 456.90466
EndFunc

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Func MyArrayAdd2(ByRef $avArray, $avValue)
    Local $iUBound1 = UBound($avArray)
    Local $iUBound2 = UBound($avValue)
    If UBound($avArray, 0) <> 2 Then
        Dim $TempArray[1][$iUBound2]
        $avArray = $TempArray
        $iUBound1 = 0
    Else
        ReDim $avArray[$iUBound1 + 1][$iUBound2]
    EndIf
    For $i = 0 To $iUBound2 - 1
        $avArray[$iUBound1][$i] = $avValue[$i]
    Next
    Return $iUBound1
EndFunc

This is my latest 2-dimensional _ArrayAdd variant, it now handles an empty array. This in concert with _ArrayDelete can now be used to dynamically build a 2-dimensional array from scratch, or remove all existing elements from an array and re-populate it from nothing. Standard loops from 0 to UBound($array)-1 will work in all cases.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...