Results 1 to 4 of 4

Thread: [RESOLVED] Passing Array ByVal

  1. #1

    Thread Starter
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397

    Resolved [RESOLVED] Passing Array ByVal

    Is there any way to pass an array so that any changes made to it are not returned?

    I've always passed arrays byref, and built copies such that any changes made would be upon the copy, to prevent backward propagation errors.

    But perhaps I could do it some other way?

    I was hoping that ByVal might now work in Net'05, but it still acts like a ByRef when passing arrays.

    For example:

    Code:
        Private Sub TestSortToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TestSortToolStripMenuItem.Click
            Dim mArr() As Integer
            ReDim mArr(5)
            Dim mI As Integer
            For mI = 1 To 5
                mArr(0) += 1
                mArr(mArr(0)) = mI
            Next
            Call ECHO_IT(mArr)
            For mI = 1 To mArr(0)
                MessageBox.Show(mArr(mI))
            Next
        End Sub
    
        Private Sub ECHO_IT(ByVal mArr() As Integer)
            Dim mI As Integer
            For mI = 1 To mArr(0)
                MessageBox.Show(mArr(mI))
                mArr(mI) = 0
            Next
        End Sub
    changes the original array.

    Is there a better method to pass an array and not return any changes made upon it?


    -Lou

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Passing Array ByVal

    It's working the same as it is supposed to. ByRef and ByVal are internally consistent for all types, this is just one that you get to think through a bit more. When you pass something in ByRef, you are passing the address of an object, while if you pass ByVal, you are passing the object itself. However, for a reference type, such as an array, the object IS just an address, so when you pass it ByRef you are passing the address of the address, while if you pass ByVal you are passing the address. This means that passing a value type ByRef (where you pass the address) is functionally the same as passing a reference type ByVal (again you are just passing the address).

    There is no way for MS to "fix" this, because there is no solution that is correct for all cases, and you certainly don't want the behavior to be different for each individual object type.

    The problem comes from the fact that if you were really to pass a copy of the array into the function, rather than just passing the address of the array, then the compiler would have to perform an implicit deep copy. After all, what is in the array? What if it was an array of objects that all used a shared database connection? There is no way to decide what needs to be copied in this case. Could the addresses of the objects be copied? Would the objects themselves have to be copied? Would they still share the same DB connection, or would they all get new connections? Since the compiler has no way of answering that question, it doesn't even try.

    This does make things consistent, though. If the item is passed ByValue, then a copy of the value is made. If tthe item was just the address of the item, then a copy of the address of the item is made. Quite consistent.

    Of course, this means that in your case.....it's business as usual, and always will be.
    My usual boring signature: Nothing

  3. #3
    Raging swede Atheist's Avatar
    Join Date
    Aug 2005
    Location
    Sweden
    Posts
    8,018

    Re: Passing Array ByVal

    An array is really a pointer to the memory address of the first element. So when you're creating an array and passing it to a method like this:

    vb Code:
    1. Private Sub MethodA()
    2.     Dim intArray() As Integer = {1,2,3,4,5}
    3.     MethodB(intArray)
    4. End Sub
    5.  
    6. Private Sub MethodB(ByVal someArray() As Integer)
    7.     For i As Integer = 0 to someArray.GetUpperBound(0)
    8.         someArray(i) = 0
    9.     Next i
    10. End Sub
    You are actually passing a pointer to MethodB. So someArray in MethodB will be pointing to the same memory address as intArray in MethodA.

    One workaround to avoid this would be to create a copy of the array and send the copy to the method.

    Edit: Dangit. Shaggy Hikers answer is the better one. Read his instead.
    Rate posts that helped you. I do not reply to PM's with coding questions.
    How to Get Your Questions Answered
    Current project: tunaOS
    Me on.. BitBucket, Google Code, Github (pretty empty)

  4. #4

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width