<<
Home , Bit

Memory and Pointers

This handout will get you oriented with the memory layout that your code has access to. It will also introduce you to pointers, a fundamental topic in the C programming language.

A 64-bit ’s View of the World A classical machine (quantum machines are different) has chips where transistors and other electrical components are attached. These electrical components can manipulate and store electric that are above or below a certain threshold. These voltages are presented to the programmer as bits of values 0 or 1, where a value of 0 represents a voltage below the threshold, and a value of 1 represents a voltage above the threshold.

Consequently, the instructions and that you write in your programs are stored in a machine’s memory as bit of 0’s and 1’s. When these instructions and data are copied to the processor, values of 1 will cause a voltage to rise above a threshold, thereby enabling electric flow through some components, while values of 0 will cause a voltage to drop below a threshold, thereby inhibiting flow through components, and this electric dance will bring about computation.

A 64-bit machine houses a processor, registers, and datapath components that can perform computations on 64 bits, or 8 , at once (i.e. a bit of 64 0’s and 1’s). A 64-bit processor can therefore read the value of a data variable that is 8 bytes large. Note that not all data variables on 64-bit machines are 8 bytes large, but some are, like long integers and pointers. ​ ​

Memory Range of a Program on a 64-bit Machine Every program that you write and compile on a machine will have access to the full range of memory provided by that machine. The program data and instructions will exist in that range of memory. There will also be free regions of memory in that accessible memory that are available for automatic and dynamic allocation by the program (see below for automatic and dynamic allocation of memory).

All memory required by your program is allocated from the full range of program accessible memory. You can think of this range as a large array of bytes. Every has a value. This value is determined by ​ ​ ​ the bit sequence within that byte. Every byte also has an address, or a location, within the accessible ​ ​ memory range. Hence, you can think of memory as a large array of bytes, starting from byte at location 0 ​ and ending with byte at location M - 1, where M is the total size of memory in bytes. On a 64-bit machine, M = 264 bytes.

Memory

Address Address Byte () () Values

0 0x0 0x12

1 0x1 0x34

2 0x2 0x56

3 0x3 0x78

......

......

......

264 - 1 0xffffffffffffffff 0xaa

Pointers are Memory Locations in a 64-bit Memory Range

A pointer is a fundamental in the C programming language. The value of a pointer variable is ​ 64 the value of a memory location. Memory locations on a 64-bit machine range from location 0 to 2 - 1, ​ the largest possible location that a program can access. Therefore, pointer values on a 64-bit machine can range from 0 to 264 − 1 as well. In hexadecimal notation, these pointer values range from 0x0000000000000000 to 0xffffffffffffffff. Notice that this is the full range of expressible natural ​ ​ numbers within 8 bytes of data1.

Memory Layout of an Executable Program on a 64-bit Machine When a C program is compiled into an executable binary that contains its instructions and data, it is ​ compiled in a way that allows the program instructions to access the full range of memory that is available on a 64-bit machine2. Therefore, the compiled program will contain data that can occupy ​ memory locations ranging from 0x0000000000000000 to 0xffffffffffffffff, and it will contain ​ ​ instructions that would reference and use the data within this range. This memory range is divided into several regions, and data variables occupy memory in different regions based on the type of these variables.

1 A hexadecimal digit represents 4 binary digits, so 16 hexadecimal digits represent 16 x 4 = 64 binary digits, or bits. Therefore, ​ 0x0000000000000000 represents 64 binary 0’s, while 0xffffffffffffffff represents 64 binary 1’s. 2 Even though this should amount to 2^64 bytes of memory, it actually amounts to 2^48 bytes of memory on most systems. ​ Memory

0xffffffffffffffff

kernel stuff

stack region (local vars)

(... grows downward)

(... grows upward)

heap region (dynamic vars)

data region (global vars)

text region (instructions)

unused

0x0000000000000000

● Global variables occupy the data memory region. ○ The memory that needs to be allocated for these variables must be known at compile time. Memory for them is allocated upon compilation and persists for the lifetime of the program that declares them. ● Local variables occupy the stack memory region. ○ Every that your program executes is automatically allocated space on the stack that is called a stack frame. A function’s local variables are allocated memory within that stack frame. ○ Automatic allocation is memory allocation that is enforced automatically when your program is compiled. Because you fully specify functions when you write your code, the ​ compiler is able to know how much memory every function will require when it is called, and hence it enforces the automatic allocation and deallocation of this memory when the program is running. ○ The memory that needs to be allocated for local variables must be known at compile time. ● Dynamic variables occupy the heap memory region. ○ Some variables need to be allocated at runtime. Memory for these variables can be allocated and freed dynamically, according to the programmer. ○ Dynamic allocation is memory allocation that happens while the program is running. One example of such an allocation is seen in Java statements that create new objects using their corresponding object constructors:

Person p = new Person();

In C, dynamic allocation looks like this: struct person { char *name; int age; } Person; Person *p = (Person *) malloc((Person));

When the above lines are executed, a new region of memory is allocated for a new object of type Person. Within that memory region, you will find the values of the object members of this new Person p (name and age).