Create a type with pointer to array

question

#1

hi all,

I’m new to Julia, and still getting used to the Julia-way of doing things. I was wondering if there is anything that would work as a pointer would in C, or as a reference variable in C++?

the particular use case I have in mind is as follows. suppose I create a new type, called “Coord”, that will store a particular coordinate system.

immutable Coord
    val::Array{Real}
    name::AbstractString
end

and use it to create my coordinate x:

x0 = 0:0.05:1
x  = Coord(x0, "mycoord")

Now I want another type, called “MyField”, which I’d like to contain a field to point to a type Coord. Something like

type MyField
    coord::Coord
    val::Array{Real}
    name::AbstractString
end

Say that I now create two such objects:

A = Field(x, x0, "A")
B = Field(x, x0, "B")

My understanding is that both A and B now contain two copies of my Coord type, right? ie, A.coord and B.coord are independent and are each occupying space in memory. This is fine for small arrays, but for larger ones memory consumption will quickly increase needlessly, since I’d be fine if A.coord and B.coord would be pointing to the same memory address. Is there a way to achieve this? In C I would achieve this with a pointer, or a reference in C++. Something like (in pseudo-code, now):

type MyField
    ptr_to_coord::(&Coord)
    val::Array{Real}
    name::AbstractString
end

where ptr_to_coord would be a pointer to the memory address of Coord… Is there a Julia-way of doing this, or am I thinking about this the wrong way?


Subtleties of type and immutable and memory layout when using ccall
#2

No, A.coord and B.coord are the same object:

julia> A.coord === B.coord
true

#3

=== returns true because Coord is immutable, and hence is defined by its value. They are actually stored separately in memory. If you want them to be the same object in memory, just use type rather than immutable.


#4

Well, in this case the majority of the memory is the array, and indeed they both use the same array, so the effect is the same.


#5

So, A.coord and B.coord are stored separately, but A.coord.val and B.coord.val point to the same memory address, is that it?
How can I know and/or check when this happens?


#6

Try

x.val[1] = 1.0

A.coord.val
B.coord.val

#7

Well, with immutable objects things can be a bit funny. They could point to the same memory space, they could point to different spaces, or they may not exist at all (the compiler may decide it doesn’t need to bother creating the objects and simply keeps the elements in the fields). This is why for instance you can’t attach finalizers to immutable objects.

But yes, they will share the same array.

You can use === on the arrays:

A.coord.val === B.coord.val

(arrays are one of the few builtin objects in Julia, but they act like mutable objects so are equal if and only if they point to the same memory).


#8

Is there a way to make sure that two given objects will be always pointing to the same memory space, then? something like references in C++?


#9

All mutable objects (this includes arrays) are (internally) object pointers in Julia. If you assign one such object to another variable, or pass one as an argument, Julia will always just copy the pointer (the underlying object is shared in memory), equivalent to a C++ reference or object pointer.


#10

(Sharing memory for mutable objects is required by the semantics of the language. If the memory weren’t shared, they wouldn’t have mutable semantics.)