Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Address of object in Julia

Tags:

julia

How do I get the address of an object obj as a plain string? The pointer_from_objref() function is close to what I want, but when I print the result I get "Ptr{Void} @0x00007f3864c40038" instead of "0x00007f3864c40038". Of course, I could simply discard the first 11 characters, but I feel like there should be a more elegant solution.

The motivation for this question is that I am working on an adjacency list based graph library, centred around the type

immutable Vertex
    neighbors::Vector{Vertex}
end

At the moment, printing a single vertex recursively prints the entire graph, which is very inconvenient. Instead, I would like print(v) to result in Vertex 0x00007f3864c40038.

like image 440
gTcV Avatar asked Feb 08 '23 19:02

gTcV


2 Answers

Using repr + UInt64 is a way:

julia> a=10
10

julia> s=repr(UInt64(pointer_from_objref(a)))
"0x0000000080012230"

julia> print(s)
0x0000000080012230

tested with Julia Version 0.4.3


Update: in Julia version >= 1.0, pointer_from_objref may not be called on immutable objects, so for the example above works, the a variable needs to be setted to a mutable type (e.g., an Array type):

julia> a = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> s=repr(UInt64(pointer_from_objref(a)))
"0x000000001214ce80"
like image 111
Gomiero Avatar answered Feb 10 '23 08:02

Gomiero


In Julia 1.7

You can do this in two ways.

For mutable types such as structs:

   julia> mutable struct foo
       a
       end

    julia> tst = foo(1)
    foo(1)
    julia> s=repr(UInt64(pointer_from_objref(a)))

However, as of Julia >= 1.0 this can not be used on immutable objects. Note the check in the function below:

function pointer_from_objref(@nospecialize(x))
    @_inline_meta
    ismutable(x) || error("pointer_from_objref cannot be used on immutable objects")
    ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), x)
end

To do this on immutable objects (which is dangerous, since the memory address of those objects is not static)

One can provide another method skipping the check:

function unsafe_pointer_from_objectref(@nospecialize(x))
    #= Warning Danger=#
    ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), x)
end
julia> struct bar
       a
       end

julia> tst = bar(1)
    bar(1)
julia> repr(UInt64(unsafe_pointer_from_objectref(tst)))
"0x000000009316f360"
like image 45
JKRT Avatar answered Feb 10 '23 10:02

JKRT