Coming from Languages without a GC (C/C++/Rust..) i am wondering what exactly is happening if an array is reallocated.
if we're in a c++ like language(pseudo code), this is considered bad:
Obj *x = xarr[2];
xarr.push(new Obj(12));
do_with(x);
running example in c++ http://ideone.com/qk7vcj
after the push, x may point to freed memory due to reallocation of xarr.
x is basically just a pointer sized integer storing the memory address of xarr[2].
if i do the same in java. this is working just fine and i am wondering why?
List<OBJ> list = new ArrayList<>();
list.add(new OBJ());
list.add(new OBJ());
list.add(new OBJ());
OBJ x = list.get(2);
for (int idx = 0; idx < 1000000; idx++) {
list.add(new OBJ());
}
do_it(x);
what exactly is x and how and why is the memory address of x changed after the array is seemingly reallocated?
obviously java is not deepcopying the array because x2 could not change x like in this code as you can see, the address of x is changing, too.
private static class OBJ {
int one;
String two;
public OBJ() {
this.one = 1;
this.two = "two";
}
}
public static void do_it(OBJ o) {
System.out.println("o.two is: " + o.two);
}
public static void main(String[] args)
{
List<OBJ> list = new ArrayList<>();
list.add(new OBJ());
list.add(new OBJ());
list.add(new OBJ());
OBJ x = list.get(2);
printAddresses("Address x", x);
for (int idx = 0; idx < 1000000; idx++) {
list.add(new OBJ());
}
OBJ x2 = list.get(2);
x2.two = "haha";
printAddresses("Address x", x);
do_it(x);
}
should not print out this
Address x: 0x525554440
Address x: 0x550882b80
o.two is: haha
full working example can be found here http://ideone.com/P3j6xF
so that begs the question how is the address of x changed after the reallocation of the list. And what exactly is the so called "reference"? I thought the so called "reference" in Java is just an ordinary pointer with something like autodereference and no pointer arithmetic because in Java everything is passed by value and not by reference. this is clearly evident in this code http://ideone.com/k4Ijq0
public static void test1(OBJ o) {
o.one = 2;
}
public static void test2(OBJ o) {
o = new OBJ();
o.two = "no reference";
}
public static void main (String[] args) throws java.lang.Exception
{
OBJ x = new OBJ();
test1(x);
test2(x);
System.out.println("x.one: " + x.one + " x.two: " + x.two);
}
printing out
x.one: 2 x.two: two
so it seems like x is behaving like a pointer but somehow java is redirecting it if necessary. How does this work? The term "reference" is extra confusing, why is it called like that?