Sign in to follow this  
Followers 0
Nutster

Weird array behaviour

19 posts in this topic

I am creating a set of sorting functions in AutoIt when I noticed a strange behaviour of array assignment. When I assign a variable from an entire array and pass the variable to a UDF ByRef, I find that the original array is affected as well. For example:

Global $aFull[100]
Global $aSorted
Global $I, $sMsg

;Generate the random number sequence
For $I = 0 To UBound($aFull) - 1
    $aFull[$I] = Random(0, 9999, True)
Next

$sMsg = "Original:  " & $aFull[0]
For $I = 1 To UBound($aFull) - 1
    $sMsg &= ", " & $aFull[$I]
Next
MsgBox(64, "Sort Test", $sMsg)

$aSorted = $aFull       
If _Sort_Bubble($aSorted) Then
    $sMsg = "Original:  " & $aFull[0]
    For $I = 1 To UBound($aFull) - 1
        $sMsg &= ", " & $aFull[$I]
    Next
    MsgBox(64, "Sort Test", $sMsg)

    $sMsg = "Bubble Sorted:  " & $aSorted[0]
    For $I = 1 To UBound($aSorted) - 1
        $sMsg &= ", " & $aSorted[$I]
    Next
    MsgBox(64, "Sort Test", $sMsg)
Else
    MsgBox(48, "Sort Test", "Bubble Sort failed!")
EndIfoÝ÷ Ø]x-ébì!z·´ß¦¢»^wH¬jË"wn·ËazX§©Ýq«¬zËayÊ)ÊÚ(qË«!Ê.Ùèµø§vØb±Úºg§µçZ,!z·Þx)Ý¢·hzË(ê'z¯y©ÞÆZ«b¢wè®Øb±·¡jø¨º²'naq«²Ø^JíæÛçîËb¢{"±«­¢+ÙÕ¹}M½ÉÑ}   Õ±¡  åIÀÌØíY±ÕÌ°
½¹ÍÐÀÌØíM­¥Á¥ÉÍÐô±Í¤(%%9½Ð%ÍÉÉä ÀÌØíY±Õ̤Q¡¸í5­ÍÕÉѡХХ̸ÉÉä($%MÑÉÉ½È Ä¤($%IÑÕɸ±Í(%±Í%U ½Õ¹ ÀÌØíY±ÕÌ°À¤±ÐìÐìÄQ¡¸í5­ÍÕÉѡХХÌÍ¥¹±¥µ¹Í¥½¹($%MÑÉÉ½È È¤($%IÑÕɸ±Í(%±Í%9½Ð%Í  ½½° ÀÌØíM­¥Á¥ÉÍФQ¡¸($%MÑÉÉ½È Ì¤($%IÑÕɸ±Í(%¹%($ìAÍͱ°Ñ¡½ÍÑÍÑÌ($ìÑհձͽÉÐ(%1½°ÀÌØí$(%1½°ÀÌØí¹MÑÉÐôÀ°ÀÌØí¹!¥ ôU ½Õ¹ ÀÌØíY±Õ̤´Ä°ÀÌØí¹1ÍÑMÝÀ((%%ÀÌØíM­¥Á¥ÉÍÐQ¡¸ÀÌØí¹MÑÉÐôÄ(($$ÀÌØí¹1ÍÑMÝÀô´Ä($%½ÈÀÌØí$ôÀÌØí¹MÑÉÐQ¼ÀÌØí¹!¥ ´Ä($$%%ÀÌØíY±ÕÍlÀÌØí%tÐìÀÌØíY±ÕÍlÀÌØí$¬ÅtQ¡¸($$$%MÝÀ ÀÌØíY±ÕÍlÀÌØí%t°ÀÌØíY±ÕÍlÀÌØí$¬Åt¤($$$$ÀÌØí¹1ÍÑMÝÀôÀÌØí$($$%¹%($%9áÐ($$ÀÌØí¹!¥ ôÀÌØí¹1ÍÑMÝÀ(%U¹Ñ¥°ÀÌØí¹1ÍÑMÝÀ±ÐìÀ(%IÑÕɸQÉÕ)¹Õ¹ìôôÐí}M½ÉÑ}    Õ±

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Share this post


Link to post
Share on other sites



You forgot to post Swap() function.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

EDIT: The below doesn't seem to invoke the issue. I will try your sort again.

Here is an example:

#include <array.au3>

Dim $myArray[100]

;Fill array with random numbers 1-100
For $X = 0 to Ubound($myArray) - 1
    $myArray[$X] = Random(1,100,1)
Next

$copyArray = $myArray

;Show array before sorting
_ArrayDisplay($myArray)

_ArraySort($myArray, 0, 0)

;Show array after sorting
_ArrayDisplay($myArray)

;Show copy of original array (unsorted)
_ArrayDisplay($copyArray)
Edited by weaponx

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I tweaked it into a runnable state like this:

#include <array.au3>

Global $aFull[10]
Global $aSorted
Global $I, $sMsg

;Generate the random number sequence
For $I = 0 To UBound($aFull) - 1
    $aFull[$I] = Random(0, 9999, True)
Next
_ArrayDisplay($aFull, "Debug: Original $aFull")

$aSorted = $aFull      
_ArrayDisplay($aSorted, "Debug: Original $aSorted")

If _Sort_Bubble($aSorted) Then
    _ArrayDisplay($aSorted, "Debug: Bubble sorted $aSorted")
Else
    MsgBox(48, "Sort Test", "Bubble Sort failed!")
EndIf

_ArrayDisplay($aFull, "Debug: $aFull after all the excitement")

Func _Sort_Bubble(ByRef $aValues, Const $bSkipFirst = False)
    Local $vTemp = ""
    If Not IsArray($aValues) Then ;Make sure that it is an array
        SetError(1)
        Return False
    ElseIf UBound($aValues, 0) <> 1 Then ;Make sure that it is single dimensioned
        SetError(2)
        Return False
    ElseIf Not IsBool($bSkipFirst) Then
        SetError(3)
        Return False
    EndIf
    ; Passed all those tests
    ; Actual bubble sort
    Local $I
    Local $nStart = 0, $nHigh = UBound($aValues) - 1, $nLastSwap

    If $bSkipFirst Then $nStart = 1
    Do
        $nLastSwap = -1
        For $I = $nStart To $nHigh - 1
            If $aValues[$I] > $aValues[$I + 1] Then
                $vTemp = $aValues[$I]
                $aValues[$I] = $aValues[$I + 1]
                $aValues[$i + 1] = $vTemp
                $nLastSwap = $I
            EndIf
        Next
        $nHigh = $nLastSwap
    Until $nLastSwap < 0
    Return True
EndFunc   ;==>_Sort_Bubble

And $aFull is unchanged after $aSorted gets sorted. So I don't see the problem.

:)

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I'm not sure either, I came up with pretty much the same thing but added StringCompare() for good measure:

#include <Array.au3>

Global $aFull[100]
Global $aSorted
Global $I, $sMsg

;Generate the random number sequence
For $I = 0 To UBound($aFull) - 1
    $aFull[$I] = Random(1, 100, 1)
Next

;Display original unsorted array
$string1 = _ArrayToString($aFull, ",")
MsgBox(64, "Sort Test", $string1)

$aSorted = $aFull      

If _Sort_Bubble($aSorted) Then
    ;Display sorted array
    $string2 = _ArrayToString($aSorted, ",")
    MsgBox(64, "Sort Test", $string2)
Else
    MsgBox(48, "Sort Test", "Bubble Sort failed!")
EndIf

;Display copy of original unsorted array
MsgBox(64, "Compare result", StringCompare($string1, _ArrayToString($aFull, ",")))

Func _Sort_Bubble(ByRef $aValues, Const $bSkipFirst = False)
    If Not IsArray($aValues) Then ;Make sure that it is an array
        SetError(1)
        Return False
    ElseIf UBound($aValues, 0) <> 1 Then ;Make sure that it is single dimensioned
        SetError(2)
        Return False
    ElseIf Not IsBool($bSkipFirst) Then
        SetError(3)
        Return False
    EndIf
    ; Passed all those tests
    ; Actual bubble sort
    Local $I
    Local $nStart = 0, $nHigh = UBound($aValues) - 1, $nLastSwap

    If $bSkipFirst Then $nStart = 1
    Do
        $nLastSwap = -1
        For $I = $nStart To $nHigh - 1
            If $aValues[$I] > $aValues[$I + 1] Then

                $temp = $aValues[$I]
                $aValues[$I] = $aValues[$I + 1]
                $aValues[$I + 1] = $temp
                
                $nLastSwap = $I
            EndIf
        Next
        $nHigh = $nLastSwap
    Until $nLastSwap < 0
    Return True
EndFunc   ;==>_Sort_Bubble
Edited by weaponx

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Hi,

I got confused by this once before, as did _Ultima_, although it all seemed to go away and not be a problem in my script when it was changed, and I never bothered following it up..

I'm clearly copying $avReference (rather than using it directly). The easiest way I got around this was to set $array[0] = $array[0] immediately after $array = $avReference

_ArrayIntroSort(),Any light would be interesting..

Best, Randall

Edited by randallc

Share this post


Link to post
Share on other sites

You forgot to post Swap() function.

Easily Fixed.

Func Swap(ByRef $vA, ByRef $vB)
    Local $T = $vA
    $vA = $vB
    $vB = $T
EndFunc   ;==>Swap

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Hi,

Interesting thta the bug returns if we use an invented "Swap" func;

; ArrayNutster.au3
Global $aFull[10]
Global $aSorted
Global $I, $sMsg

;Generate the random number sequence
For $I = 0 To UBound($aFull) - 1
    $aFull[$I] = Random(0, 9999, True)
Next

$sMsg = "Original:  " & $aFull[0]
For $I = 1 To UBound($aFull) - 1
    $sMsg &= ", " & $aFull[$I]
Next
MsgBox(64, "Sort Test", $sMsg)

$aSorted = $aFull
If _Sort_Bubble($aSorted) Then
    $sMsg = "Original:  " & $aFull[0]
    For $I = 1 To UBound($aFull) - 1
        $sMsg &= ", " & $aFull[$I]
    Next
    MsgBox(64, "Sort Test", $sMsg)

    $sMsg = "Bubble Sorted:  " & $aSorted[0]
    For $I = 1 To UBound($aSorted) - 1
        $sMsg &= ", " & $aSorted[$I]
    Next
    MsgBox(64, "Sort Test", $sMsg)
Else
    MsgBox(48, "Sort Test", "Bubble Sort failed!")
EndIf

Func _Sort_Bubble(ByRef $aValues, Const $bSkipFirst = False)
    Local $vTemp = ""
    If Not IsArray($aValues) Then ;Make sure that it is an array
        SetError(1)
        Return False
    ElseIf UBound($aValues, 0) <> 1 Then ;Make sure that it is single dimensioned
        SetError(2)
        Return False
    ElseIf Not IsBool($bSkipFirst) Then
        SetError(3)
        Return False
    EndIf
    ; Passed all those tests
    ; Actual bubble sort
    Local $I
    Local $nStart = 0, $nHigh = UBound($aValues) - 1, $nLastSwap

    If $bSkipFirst Then $nStart = 1
    Do
        $nLastSwap = -1
        For $I = $nStart To $nHigh - 1
            If $aValues[$I] > $aValues[$I + 1] Then
                swap($aValues[$I], $aValues[$I + 1])
;~                 $vTemp = $aValues[$I]
;~                 $aValues[$I] = $aValues[$I + 1]
;~                 $aValues[$i + 1] = $vTemp
                $nLastSwap = $I
            EndIf
        Next
        $nHigh = $nLastSwap
    Until $nLastSwap < 0
    Return True
EndFunc   ;==>_Sort_Bubble
Func swap(ByRef $aValues1, ByRef $aValues2)
    Local $vTemp = $aValues1
    $aValues1 = $aValues2
    $aValues2 = $vTemp
EndFunc   ;==>swap

So my guess is that it has does something to do with that! [as intimated by weaponX noting it was missing!]

Best, Randall

Edited by randallc

Share this post


Link to post
Share on other sites

Confirmed, from my version earlier (with no symptoms), just putting the Swap() function back causes $aFull to wind up the same as $aSorted:

#include <array.au3>

Global $aFull[10]
Global $aSorted
Global $I, $sMsg

;Generate the random number sequence
For $I = 0 To UBound($aFull) - 1
    $aFull[$I] = Random(0, 9999, True)
Next
_ArrayDisplay($aFull, "Debug: Original $aFull")

$aSorted = $aFull
_ArrayDisplay($aSorted, "Debug: Original $aSorted")

If _Sort_Bubble($aSorted) Then
    _ArrayDisplay($aSorted, "Debug: Bubble sorted $aSorted")
Else
    MsgBox(48, "Sort Test", "Bubble Sort failed!")
EndIf

_ArrayDisplay($aFull, "Debug: $aFull after all the excitement")

Func _Sort_Bubble(ByRef $aValues, Const $bSkipFirst = False)
    Local $vTemp = ""
    If Not IsArray($aValues) Then ;Make sure that it is an array
        SetError(1)
        Return False
    ElseIf UBound($aValues, 0) <> 1 Then ;Make sure that it is single dimensioned
        SetError(2)
        Return False
    ElseIf Not IsBool($bSkipFirst) Then
        SetError(3)
        Return False
    EndIf
    ; Passed all those tests
    ; Actual bubble sort
    Local $I
    Local $nStart = 0, $nHigh = UBound($aValues) - 1, $nLastSwap

    If $bSkipFirst Then $nStart = 1
    Do
        $nLastSwap = -1
        For $I = $nStart To $nHigh - 1
            If $aValues[$I] > $aValues[$I + 1] Then
                Swap($aValues[$I], $aValues[$I + 1])
                $nLastSwap = $I
            EndIf
        Next
        $nHigh = $nLastSwap
    Until $nLastSwap < 0
    Return True
EndFunc   ;==>_Sort_Bubble

Func Swap(ByRef $vA, ByRef $vB)
    Local $T = $vA
    $vA = $vB
    $vB = $T
EndFunc   ;==>Swap

That's just..., just..., wrong...

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Here is a much more minimal demonstrator script for the issue:

#include <array.au3>

Global $avOne[2] = [1, 2]
Global $avTwo = $avOne

_Swap($avTwo[0], $avTwo[1])

_ArrayDisplay($avOne, "Debug: $avOne")
_ArrayDisplay($avTwo, "Debug: $avTwo")

Func _Swap(ByRef $vA, ByRef $vB)
    Local $T = $vA
    $vA = $vB
    $vB = $T
EndFunc   ;==>Swap

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Wow. Strange behavior. Seems to only effect arrays.

Global $var1 = "Yes"
Global $var2 = $var1

change($var1)

MsgBox(0,"","Var1: " & $var1 & @CRLF & "Var2: " & $var2)

Func change(ByRef $somevar)
    $somevar = "NO"
EndFunc

Share this post


Link to post
Share on other sites

Using _ArraySwap() is doing the same thing.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

Shouldn't this be a bug report by now...?

:)

Looks like a Microsoft start for the new year.

Share this post


Link to post
Share on other sites

I think it probably is a bug and I'm wondering if ByRef isn't broken.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

Time to post PsaltyDS's example in Bug Reports. Thanks for the consideration guys.


David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Share this post


Link to post
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
Sign in to follow this  
Followers 0