Address of object in Julia
Asked Answered
N

2

5

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.

Noninterference answered 7/2, 2016 at 9:48 Comment(1)
OT, but I assume you know about github.com/JuliaGraphs/LightGraphs.jl and github.com/JuliaLang/Graphs.jl.Salutation
O
9

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"
Otoscope answered 7/2, 2016 at 11:16 Comment(2)
What about the immutable type?Calvo
@RubemPacelli I provided an example, on how it can be done. (It is dangerous to do however)Hardily
H
2

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"
Hardily answered 22/6, 2022 at 15:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.