On Thu, 21 May 2009 04:51:16 -0400, MLT wrote: > After a discussion on digitalmars.D I played with arrays a bit. Look at the > following code: > int[] a = [1,2,3,4,5,6,7,8,9] ; > int[] b = a ; > a ~= 10 ; > b ~= 11 ; > b[0] = 12 ; > Stdout(b).newline ; > Stdout(a).newline ; > > The result is: > [12, 2, 3, 4, 5, 6, 7, 8, 9, 11] > [12, 2, 3, 4, 5, 6, 7, 8, 9, 11] > > Which means that even though b was set only to a[0..10], after expanding b, > also has direct access to element a[10]. But > int[] a = [1,2,3,4,5,6,7,8,9] ; > int[] b = a ; > a ~= 10 ; > b.length = b.length+1 ; > b[0] = 11 ; > Stdout(b).newline ; > Stdout(a).newline ; > > Gives > [11, 2, 3, 4, 5, 6, 7, 8, 9, 0] > [11, 2, 3, 4, 5, 6, 7, 8, 9, 0] > > Now b is expanded in length, but a side effect is that a[10] is set to 0 > (i.e. initialized). > > In the end, I think b can only see things that happen to a[10] after it > expanded, but not before. It seems there is no way for the following to work: > int[] a = [1,2,3,4,5,6,7,8,9] ; > int[] b = a ; > a ~= 10 ; > > At this point, element a[10]=10 will never be visible to b. b can expand to > it, but by doing that, a[10] will be overwritten. > > Is this on purpose? It could also be useful to have b.length=b.length+1 which > only initializes memory that has not been initialized before.
Yes it is on purpose. Here is what is happening ... The contents of the array variable is actually a 2-element struct {addr, length}. When you assign one array to another, that struct is what is copied, not the array data itself. int[] a = [1,2,3,4,5,6,7,8,9] ; // Now 'a' contains {adr, 9} int[] b = a ; // Now 'b' contains {adr, 9} a ~= 10 ; // Now 'a' contains {adr, 10} -- The address doesn't change -- because the buffer allocation -- still enough room for another element. b ~= 11 ; // Now 'b' contains {adr, 10} -- The address doesn't change -- because the buffer allocation -- still enough room for another element -- And that new element overwrote the '10' -- appended to 'a'. b[0] = 12 ; // The element at address 'adr' is modified. // As both 'a' and 'b' point to the same area // it appears that updating 'b' changes 'a'. The safe way to copy the data of an array is to do ... int[] a = [1,2,3,4,5,6,7,8,9] ; int[] b = a.dup ; // COPY a's data to to b. a ~= 10 ; b ~= 11 ; b[0] = 12 ; The result should now be: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [12, 2, 3, 4, 5, 6, 7, 8, 9, 11] So remember, assigning one array to another is just creating an alias to the original array. You end up with two arrays pointing to the same data buffer. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell