Address of a variable

From Rosetta Code

Jump to: navigation, search
Task
Address of a variable
You are encouraged to solve this task according to the task description, using any language you may know.

Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.

You may see other such operations in the Basic Data Operations category, or:

Demonstrate how to get the address of a variable and how to set the address of a variable.

Contents

[edit] Ada

[edit] Get The Address

The_Address : System.Address;
I : Integer;
The_Address := I'Address;

[edit] Set The Address

Set the address of a variable to address A100 in hexadecimal

I : Integer;
for I'Address use 16#A100#;

Set the address of one variable to the address of another variable, creating an overlay.

I : Integer;
J : Integer;
for I'Address use J'Address;

[edit] ALGOL 68

Basically ALGOL 68 refuses to let the programmer access the memory directly. The language does allow "references" any variables. These references are effectively the address a particular variable. But the value of the actual address is not available for printing or any arithmetic.

[4]INT test := (222,444,666,888);
REF INT reference := test[3];
REF INT(reference) := reference + 111;
print(("test value is now: ",test))

Output:

test value is now:        +222       +444       +777       +888

The other reason specific addresses are using in languages like C to manipulate devices. For this purpose site are expected to implement channels for their programmers to use. To quote the ALGOL 68 Revised Report: A "channel" corresponds to one or more physical devices (e.g., a card reader, a card punch or a line printer, or even to a set up in nuclear physics the results of which are collected by the computer), or to a filestore maintained by the operating system[1].

To establish a channel with such a device there is a special standard procedure:
PROC establish = (REF FILE file, STRING idf, CHANNEL chan, INT p, l, c) INT: ~

Where the idf string is text describing which device to open, and possibly options. And chan is the actual device type. Standard CHANNELs in ALGOL 68 are stand in channel, stand out channel, and stand back channel. These determine the type of the pre opened stdio FILEs stand in, stand out, and stand back. A site would be expected to implement their own CHANNELs for network connections, database queries and particle accelerators etc.

[edit] Argile

[edit] Get the address

Works with: Argile version 1.0.0

use std, array		(: array.arg also defines pointer operators :)
let var = 42
let ptr = &var (: value of ptr is address of var :)
print var (: prints 42 :)
(*ptr)++ (: increments value pointed by ptr :)
print var (: prints 43 :)

[edit] Set the address

Since we cannot set address of a variable, we use a macro that returns a reference. Works with: Argile version 1.0.0

use std, array
=:mac:= -> int& { * (0x400000 as int*) }
printf "%x\n" mac (: may crash depending on operating system :)
 

[edit] AutoHotkey

Getting or setting the address of a variable is not supported as a builtin function. However, you can get the address of contents pointed to by the variable structure var

msgbox % &var

[edit] BASIC

Many BASICs, especially older flavors like QuickBasic, lack the ability to set a variable's address (and indeed, they pretty much all lack the ability to work with pointers in any fashion).

'get a variable's address:
DIM x AS INTEGER, y AS LONG
y = VARPTR(x)
 
'can't set the address, but can access a given memory location... 1 byte at a time
DIM z AS INTEGER
z = PEEK(y)
z = z + (PEEK(y) * 256)

[edit] BBC BASIC

The original BBC BASIC doesn't provide an address-of operator, but BBC BASIC for Windows does:

REM get a variable's address:
y% = ^x%
 
REM can't set a variable's address, but can access a given memory location (4 bytes):
x% = !y%

[edit] C#

Use of pointers in C# is restricted to unsafe sections of code, which is enabled in Microsoft's C# compiler with the commandline parameter /unsafe or in Mono's C# compiler with -unsafe (or --unsafe in older versions).

[edit] Get the address

Note that void* is a "pure" address which doesn't carry the type information anymore. If you need the type information (e.g. to recover the variable itself in a type safe manner), use a pointer to the appropriate type instead; in this case int*.

unsafe
{
int i = 5;
void* address_of_i = &i;
}

[edit] C / C++

Works with: gcc/ g++

[edit] Get the address

Note that void* is a "pure" address which doesn't carry the type information anymore. If you need the type information (e.g. to recover the variable itself in a type safe manner), use a pointer to the appropriate type instead; in this case int*.

int i;
void* address_of_i = &i;

[edit] Set the address

While C++ doesn't directly support putting a variable at a given address, the same effect can be achieved by creating a reference to that address:

int& i = *(int*)0xA100;

Overlaying of variables is done with anonymous unions; however at global/namespace scope such variables have to be static (i.e. local to the current file):

static union
{
  int i;
  int j;
};

C++ only: An alternative (and cleaner) solution is to use references:

int i;
int& j = i;

Note that in this case, the variables can be non-static.

[edit] COBOL

Using OpenCOBOL 1.1pre-release, which includes a few features from the draft 20xx standard efforts.

[edit] Get Address

use the ADDRESS OF clause.

 
data division.
working-storage section.
01 ptr usage pointer.
01 var pic x(64).
 
procedure division.
set ptr to address of var.
 

[edit] Set Address

Set address of a variable: using BASED clause. there are other methods, in particular LINKAGE SECTION variables

 
OCOBOL*> Rosetta Code set address example
*> tectonics: cobc -x setaddr.cob && ./setaddr
program-id. setaddr.
data division.
working-storage section.
01 prealloc pic x(8) value 'somedata'.
01 var pic x(8) based.
procedure division.
set address of var to address of prealloc
display var end-display
goback.
end program setaddr.
 

[edit] D

Take the address of a variable:

int i; int* ip = &i;

Using a numeric value:

int* ip = cast(int*) 0xdeadf00d;

Locating a "regular" variable at a specific address is not possible.

The closest thing is passing a dereferenced pointer to a reference parameter.

void test(ref int i) { writefln(&i); } void main() { test(*(cast(int*) 0xdeadf00d)); }
 

[edit] Delphi

Turbo/Borland Pascal and Delphi (Object Pascal) support the @ ( address of ) operator and the var : [type] absolute declaration.

To get the address of any variable, structure, procedure or function use the @ operator.

 var
   Int : integer ;
   p   : ^integer ;
 begin
   P := @int ;
   writeln(p^);
 end;

A variable can be declared as absolute ie: to reside at a specific address.

 Var
   CrtMode : integer absolute $0040 ;
   Str     : string[100] ;
   StrLen  : byte absolute Str ;

[edit] Forth

Variables and created memory blocks return their address when referenced. The "fetch" operator @ could also be pronounced "dereference".

variable foo
foo .  \ some large number, an address
8 foo !
foo @ .  \ 8

You can define a constant or value with an address, which then acts like a variable. This can be used to refer to fixed addresses (such as I/O ports), graphics buffers, or allocated memory.

$3F8 constant LPT1:
8 LPT1: !
100 cells allocate throw value buffer
42 buffer 20 cells + !

[edit] Fortran

Works with: Fortran version 90 and later

program test_loc
 
implicit none
integer :: i
real :: r
 
i = loc (r)
write (*, '(i0)') i
 
end program test_loc

Note: loc is a common extension that is implemented by e.g. the Intel Fortran Compiler, G95 and gfortran.

[edit] J

J hides the details of pointers and memory allocation from the programmer, so it is rarely, if ever, neccesary to do this. However, for those times when there is no better substitute, J provides access to these low-level details:

   var      =: 52                NB.  Any variable (including data, functions, operators etc)
var_addr =: 15!:6<'var' NB. Get address
new_var =: 15!:7 var_addr NB. Set address

[edit] NewLisp

[edit] Get Address

(set 'a '(1 2 3))
(address a)

[edit] Oberon-2

[edit] Get Address

VAR a: LONGINT;
VAR b: INTEGER;

b := 10;
a := SYSTEM.ADR(b); (* Sets variable a to the address of variable b *)

[edit] Set Address

SYSTEM.PUT(a, b); (* Sets the address of b to the address of a *)

[edit] Perl

To get the address, get the reference to a variable, and either stringify it, or use Scalar::Util's refaddr() to get just the address. Also see Devel::Peek.

use Scalar::Util qw(refaddr);
print refaddr(\my $v), "\n"; # 135691508

Use Devel::Pointer::PP if you want to dereference a certain address in memory.

Changing the address of a variable is not easily possible, but see perlapi. Wanting to go against the automatic memory management is a sign that this is only used to hack around the deficiencies of dafter languages. I can imagine address munging is commonly used to make variable aliasing possible, but Perl already has a higher level syntax for that.

Simple reference (address) manipulation.

my $a = 12;
my $b = \$a; # get reference
$$b = $$b + 30; # access referenced value
print $a; # prints 42

Example how to make variable overlay.

my $a = 12;
our $b; # you can overlay only global variables (this line is only for strictness)
*b = \$a;
print $b; # prints 12
$b++;
print $a; # prints 13

[edit] PicoLisp

The PicoLisp function 'adr' returns the address of a variable. A variable may be either a symbol or a list cell in PicoLisp.

The returned address is a number representing an encoded pointer. For symbols, it is a negative number, and for cells a positive number. The same function 'adr' can then be used to convert that pointer back to the original object.

: (setq X 7)
-> 7
 
: (adr 'X)
-> -2985527269106
 
: (val (adr -2985527269106))
-> 7
 
: (set (adr -2985527269106) '(a b c))
-> (a b c)
 
: X
-> (a b c)

[edit] PL/I

 
declare p pointer;
k = addr(b); /* Obtain address of variable, stored in integer variable k */
p = addr(q); /* assigns address to pointer variable p. */
 

[edit] PowerBASIC

'get a variable's address:
DIM x AS INTEGER, y AS LONG
y = VARPTR(x)
 
'can't set the address of a single variable, but can access memory locations
DIM z AS INTEGER
z = PEEK(INTEGER, y)
 
'or can do it one byte at a time
DIM zz(1) AS BYTE
zz(0) = PEEK(BYTE, y)
zz(1) = PEEK(BYTE, y + 1)
'(MAK creates an INTEGER, LONG, or QUAD out of the next smaller type)
z = MAK(INTEGER, zz(0), zz(1))
 
'*can* set the address of an array
DIM zzz(1) AS BYTE AT y
'zzz(0) = low byte of x, zzz(1) = high byte of x

[edit] PureBasic

Get the address of a variable using the '@' operator.

a.i = 5
MessageRequester("Address",Str(@a))


Set the address of a structured pointer. The pointer can be dereferenced to interact with it's data. Ensure that there is access to the memory address that is assigned to the pointer (i.e. part of allocated memory).

a.i = 5
*b.Integer = @a ;set *b equal to the address of variable a
*c.Integer = $A100 ;set *c to point at memory location $A100 (in hex)
 
 
MessageRequester("Address",Str(*b)) ;display the address being pointed at by *b
MessageRequester("Value",Str(*b\i)) ;de-reference the pointer *b to display the data being pointed at

[edit] Python

Python traditionally doesn't support low-level operations on memory addresses, except in the limited sense that one can use the mmap module where it's available, and manipulate offsets into memory map objects...including serializing other objects into and out of the memory mapping. New versions of Python support a ctypes module which permits some low level address operations on C-type objects (see C-types Reference for details).

The Python id() function returns a unique ID for any object. This just happens to be implemented as the base address of the object in C Python; but that is not guaranteed by the semantics of the language and should not be considered a standard, nor used as such.

foo = object()  # Create (instantiate) an empty object
address = id(foo)

In addition some folks have written binary Python modules which implement "peek" and "poke" operations, but these are non-standard.

[edit] Tcl

It is highly unusual to want to directly manipulate the address of a variable in Tcl, as it is a thoroughly unsafe operation. Indeed, Tcl does not expose any mechanism to do so at the script level. However, Tcl does contain a C-level API function, Tcl_LinkVar, to arrange for a variable's value to always reflect the contents of a particular address in memory. (See Machine Address for an example of how to do that.)

However, that's not the only way of doing it. You can also use the critcl library to put C code directly inside a Tcl script and so work with addresses directly that way.
Library: critcl

package require critcl
# This code assumes an ILP32 architecture, like classic x86 or VAX.
critcl::cproc peek {int addr} int {
union {
int i;
int *a;
} u;
 
u.i = addr;
return *u.a;
}
critcl::cproc poke {int addr int value} void {
union {
int i;
int *a;
} u;
 
u.i = addr;
*u.a = value;
}
package provide poker 1.0

Demonstrating:

package require poker
 
# Increment a memory location; this will probably crash if you try for real.
# We don't define how to get a good address, but it's not usually a problem
# for embedded programming...
set where 0x12340
poke $where [expr {[peek $where] + 1}]

Have great care with this sort of code; the damage you can do by writing to random locations is considerable and being able to read from anywhere could allow information to flow to otherwise unauthorized programs.

[edit] Toka

[edit] Get the Address

The default behaviour of a data element in Toka is to return its address. This makes obtaining the address trivial:

variable foo
foo .

[edit] Set the Address

You can manually assign a name to any memory address (or other number), but you should make sure it's part of allocated memory first.

 hex abcdef is-data foo
 foo .

[edit] Visual Basic .NET

Visual Basic uses managed memory that can be moved around at any time. If a memory address for a variable is needed, the address is created first and then its contents copied.

[edit] Get the Address

Allocates a stable address in unmanaged memory, copies a variable to it, then returns the address itself.

 Dim x = 5
 Dim ptrX As IntPtr
 ptrX = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(Integer)))
 Marshal.StructureToPtr(5, ptrX, False)
 Dim addressX = ptrX.ToInt64

[edit] Set the Address

Sets the pointer to the address A100 in hex.

 Dim ptrX As New IntPtr(&HA100)
Personal tools
Support