2.10.1 Pointers and Addresses

The Linux operating system uses a technique called virtual memory to provide each user process with its own virtual view of the memory resources on your system. A virtual view of memory resources is referred to as an address space. An address space associates a range of address values, either [0 ... 0xffffffff] for a 32-bit address space or [0 ... 0xffffffffffffffff] for a 64-bit address space, with a set of translations that the operating system and hardware use to convert each virtual address to a corresponding physical memory location. Pointers in D are data objects that store an integer virtual address value and associate it with a D type that describes the format of the data stored at the corresponding memory location.

You can explicitly declare a D variable to be of pointer type by first specifying the type of the referenced data and then appending an asterisk (*) to the type name. Doing so indicates you want to declare a pointer type, as shown in the following statement:

int *p;

This statement declares a D global variable named p that is a pointer to an integer. The declaration means that p is a 64-bit integer with a value that is the address of another integer located somewhere in memory. Because the compiled form of your D code is executed at probe firing time inside the operating system kernel itself, D pointers are typically pointers associated with the kernel's address space. You can use the arch command to determine the number of bits that are used for pointers by the active operating system kernel.

If you want to create a pointer to a data object inside of the kernel, you can compute its address by using the & operator. For example, the operating system kernel source code declares an unsigned long max_pfn variable. You could trace the address of this variable by tracing the result of applying the & operator to the name of that object in D:

trace(&`max_pfn);

The * operator can be used to refer to the object addressed by the pointer, and acts as the inverse of the & operator. For example, the following two D code fragments are equivalent in meaning:

q = &`max_pfn; trace(*q);

trace(`max_pfn); 

In this example, the first fragment creates a D global variable pointer q. Because the max_pfn object is of type unsigned long, the type of &`max_pfn is unsigned long * (that is, pointer to unsigned long), implicitly setting the type of q. Tracing the value of *qfollows the pointer back to the data object max_pfn. This fragment is therefore the same as the second fragment, which directly traces the value of the data object by using its name.