1

I'm instantiating one array 'array1' by another 'array2' and then attempting to modify 'array2', which changes 'array1'. After many hours I realised that it may be a call-by- or a pass-by- ref/value error. Can someone please help me solve this and put me in the right direction?

    int[] src = {0,4,3,2,1};
    int[] dest = src;

    dest[0] = dest[0] + 2;

    for (int node: dest) {
        System.out.print(node + " ");
    }

    System.out.println("");
    for (int node: src) {
        System.out.print(node + " ");
    }

This produces:

2 4 3 2 1

2 4 3 2 1

i.e. the source array gets modified too. Thanks in advance.

Goldfishy
  • 53
  • 3
  • Java never implicitly copies objects. – SLaks Feb 07 '14 at 17:55
  • Both objects (`src` and `dest`) hold the same reference, so any change in the state on one of them will be reflected in the other. – Luiggi Mendoza Feb 07 '14 at 17:56
  • Are you trying to modify `dest` without modifying `src`? – rgettman Feb 07 '14 at 17:56
  • Create different arrays and initialize each entry with the same value. You can use [`System.arrayCopy`](http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29) and save some time. – Luiggi Mendoza Feb 07 '14 at 17:57

5 Answers5

5

When you do

int[] dest = src;

both variables are referencing to the same position in memory. In other words, they are referencing to the same array. You can try using Arrays.copyOf:

int[] dest = Arrays.copyOf(src, src.length);

Edit: As @BackSlach commented, you can also use clone():

int[] dest = src.clone(); //clone() is a method present in every object in java

As a third alternative you can use System.arrayCopy()

int[] dest = new int[src.length];
System.arraycopy(src, 0, dest, 0, src.length);

Note that they have similar performance.

Community
  • 1
  • 1
Christian Tapia
  • 33,620
  • 7
  • 56
  • 73
2

You will need to create a copy of the src array in dest, so that when you modify dest, you don't also modify src. Just saying

int[] dest = src;

doesn't copy the array; it just creates another references to the same array. Create a copy:

int[] dest = new int[src.length];
System.arraycopy(src, 0, dest, 0, src.length);
rgettman
  • 176,041
  • 30
  • 275
  • 357
0

You're right, thats the source of your problem.

What you can do about it is to write a copy method that loops over your array and writes all the numbers to the new array.

Please keep in mind that this will only work for primitive types like int. If you have objects in your array, they are passed by reference aswell so deep-copying an array of any object needs some more work.

Also check out the clone() method, which can be overloaded to provide a mechanism to copy an object you're implementing.

markusthoemmes
  • 3,080
  • 14
  • 23
  • @Christian oh, wasn't aware of that. You never stop learning, thanks for mentioning :). – markusthoemmes Feb 07 '14 at 18:01
  • _Also check out the clone() method, which can be overloaded to provide a mechanism to copy an object._ Not in this case: you can't extend array, so you can't overload (override) that method. – BackSlash Feb 07 '14 at 18:08
  • @BackSlash Yes I'm aware of that, but i thought it would be worth mentioning it to make the OP aware of future problems with Object copying. – markusthoemmes Feb 07 '14 at 18:10
0

It has nothing to do with calling/passing. When you do

int[] dest = src;

then dest points to the same object that src points to. Therefore, a modification in dest can also be seen in src:

           +---+---+---+---+---+
src -----&gt | 0 | 4 | 3 | 2 | 1 | &lt----- dest
           +---+---+---+---+---+


dest[0] = dest[0] + 2;


           +---+---+---+---+---+
src -----&gt | 2 | 4 | 3 | 2 | 1 | &lt----- dest
           +---+---+---+---+---+

src[0] is 2 now as well, even though you modified dest.

As has been suggested, you can use Arrays.copyOf() to produce a new, distinct array with the same contents as src.

int[] dest = Arrays.copyOf(src, src.length);

Now, we have this situation:

            +---+---+---+---+---+
src  -----&gt | 0 | 4 | 3 | 2 | 1 |
            +---+---+---+---+---+

            +---+---+---+---+---+
dest -----&gt | 0 | 4 | 3 | 2 | 1 |
            +---+---+---+---+---+


dest[0] = dest[0] + 2;


            +---+---+---+---+---+
src  -----&gt | 0 | 4 | 3 | 2 | 1 |
            +---+---+---+---+---+

            +---+---+---+---+---+
dest -----&gt | 2 | 4 | 3 | 2 | 1 |
            +---+---+---+---+---+

Notice that the modification to dest did not affect src.

arshajii
  • 127,459
  • 24
  • 238
  • 287
0

You are thinking on the right lines: everything that isn't a primitive type is passed by reference in Java.

When the following is executed, you are declaring a new reference to the same array in memory:

int[] dest = src;

So you need to declare a new array. You could then either copy the values of the elements of the first array to the second one 'manually' in a loop, or use the arraycopy method in the System namespace

http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy

Ben Griffiths
  • 1,676
  • 15
  • 13