Write a script to declare a variable or constant and print its location in the memory.
This is a challenge which can only be solved in some languages. Many, if not most, hide the actual memory locations from the user.
There's not much to it. The
\
operator returns
a reference to its argument. And a reference in numeric context
is the memory location of the reference.
say+0+\+0
Since +0
is a constant, \+0
is a reference to it. If its an argument
of the addition operator (+
), it's put in numeric context, and we get
memory address.
Adding +0
to it is a no-op. So +0+\+0
is the memory address of
the constant +0
. Which we print with say
.
Find the full program on GitHub.
In C, the &
operator returns a pointer to its argument; and a
pointer is basically a memory location. We can print this straight
away using the %p
specifier for printf
, however, this
would print the address in hex format.
To use the same format as the output for our solutions in different
languages, we cast the pointer to a long long
, and print this.
int main (void) {
int i;
printf ("%lld\n", (long long) &i);
return (0);
}
Find the full program on GitHub.
In Fortran, the loc
function returns the memory address
of a variable:
program ch1
implicit none
integer :: i
print *, loc(i)
end
Find the full program on GitHub.
Like C, in Go, &
returns a references to its argument,
And you can just print that as a number:
func main () {
x := 0
fmt . Printf ("%d\n", &x)
}
Find the full program on GitHub.
Pascal has pointers, but they aren't addresses in the sense they are in C. Depending on the flavour of Pascal, you may, or may not be able to get the memory location. We use the Free Pascal compiler, which does have a way to extract the address of a pointer.
The function addr
takes a pointer as argument, and returns a
pointer to a Word containing a memory address.
The latter pointer can be dereferenced and printed.
var i: Integer;
p: ^Integer;
w: ^Word;
begin
p := @i;
w := addr (p);
writeln (w^);
end.
Find the full program on GitHub.
The id
function returns the identify of an object, which
is guaranteed to be unique. Due to an implementation detail, this
is the memory address.
print (id (0))
Find the full program on GitHub.
In R, we have to work hard! We even have to work much harder than C.
x <- 0
cat (sprintf ("%.0f\n",
as.numeric (
paste0 ("0x",
substring (
sub (" .*$", "",
capture.output (.Internal (inspect (x)))), 2)))))
We start off with .Internal (inspect (x))
write a bunch of
information to standard output. This information looks like:
@7fc083998d20 14 REALSXP g0c1 [REF(3)] (len=1, tl=0) 0
The memory address starts right after the leading @
. Since we want
to extract just the memory address, and remove the rest, we want to
capture what would normally be written to standard out. This is
what capture.output
does — it returns what otherwise would have
been written to standard output.
We then remove everything from the first space onwards, using
sub
. This takes a pattern (" .*$"
), a replacement (""
— the
empty string), and a string to act upon (the result of
capture.output
).
Next step is to get rid of the leading @
, by using substring
.
We're now have the memory address, but as a string of hex digits.
To turn this into a number, we first prepend 0x
using paste0
and then turn it into a number with as.numeric
. We then turn
it back in to a string, but this time as a decimal number using
sprintf
.
Finally, we print the memory address using cat
.
Find the full program on GitHub.
In Ruby, object_id
returns
a unique id. For objects which aren't nil
, true
, false
, Fixnums,
Symbols, this returned number has a simple relation to the memory
location of the object.
puts (Object . new . object_id << 1)
Find the full program on GitHub.