3

I don't understand why the variable initialCoordinates is changing. When I run the program, initialCoordinates changes values after each run of the loop.

int[] initialCoordinates = { 26, 0 };
int[] positions = { 1, 2, 3, 4 };
int[][] coordinates = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
for (int i = 0; i < 4; i++) {
    System.out.println("Initial: " + initialCoordinates[1]);
    coordinates[i] = initialCoordinates;
    coordinates[i][1] += positions[i];
}
4
  • 8
    Have you tried stepping through with a debugger and watching the initialCoordinates vairable? Commented Nov 8, 2018 at 18:06
  • 3
    Welcome to Stack Overflow. You need to read up on references in Java. An array variable has reference type. Commented Nov 8, 2018 at 18:08
  • 3
    Arrays are references in Java, which emits these sort of bugs in what was conjected to be a safe language. Upvote for sympathy! Commented Nov 8, 2018 at 18:08
  • and there are no 2 dimensional matrix, just array containing arrays... Commented Nov 8, 2018 at 18:54

3 Answers 3

11

In your example you're setting coordinates[i] to initialCoordinates.

Then in the next line you're executing coordinates[i][1] = ..., that's when you're accesing initialCoordinates indirectly through coordinates[i] and changing the the value of initialCoordinates[1].

Sign up to request clarification or add additional context in comments.

2 Comments

To add, if you do not want intialCoordinates to change. You need to create a copy of the array initialCoordinates in every iteration and assign that to the coordinates[i]. See how to create copy of an array
Does this issue also exist in C#, or any other languages. Also, is there a specific reason why this exists?
2

As Mark said, you are accessing initialCoordinates with the coordinates variable because you assigned it by reference. This means that after coordinates [i]=initialCoordinates;, coordinates[i] will then reference the same memory address that initalCoordinates does so that when one changes the other changes also.

What you probably wanted to do is copy the values which would have the effect of assigning it by value. You can do that using System.arraycopy (See this answer). By assigning by value, you allocate a separate chunk of memory to hold the values for coordinates[i] which will be copied from initialCoordinates rather than having both variables pointing to the same thing in memory.

int [] initialCoordinates = {26,0};
int [] positions={1,2,3,4};
int [][] coordinates = {{0,0},{0,0},{0,0},{0,0}};
for(int i=0;i<4;i++){
    System.out.println("Initial: "+initialCoordinates[1]);
    System.arraycopy(initialCoordinates, 0, coordinates[i], 0, initialCoordinates.length);
    coordinates [i][1]+=positions[i];
}

Comments

2

I will attempt to show you, what is approximately going on in java memory.

  • first you created instances in the stack, which points to objects in the heap

enter image description here

  • then you changed the pointer of coordinates[0], and both variables - initialCoordinates and coordinates[i] point to the same object in the heap

  • so, when you changed coordinates[0], you also changed the object in the heap. The initialCoordinates also refers to object in the heap, so intialCoordinates were also "changed"..

enter image description here

1 Comment

I like this explanation however there are a lot of typos in your text & images. And in your last image only coordinates[0] points to something but there's not a single arrow to coordinates in the heap.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.