Learning more
- Unit notes (on the course site’s Lectures menu)
- Textbook readings (see the course site’s Textbook page)
- Lecture code at https://github.com/cs61/cs61-lectures/
- This lecture’s directory:
datarep-addr
- This lecture’s directory:
Addresses
- An address is the numeric value that names the location of a byte in memory
- Every byte of memory has a distinct address
- Each object occupies a contiguous range of addresses
- A four-byte object occupies four adjacent addresses
- The number of bytes required to hold an object is called its size
- All objects of the same type have the same size
sizeof(x)
returns the size of object or typex
Primary memory
- Primary memory is the kind of computer memory with addresses
- But actual computer hardware has many other kinds of memory!
- Including registers, which are very efficient to access and in which computation is actually performed
- Registers do not have addresses
- Compilers move objects to and from registers as the program requires
Pointers
- A pointer is a C++ object that holds the location of a different
object
- For instance,
int* ptr
can hold the location of anint
object
- For instance,
- A pointer is an object and points to an object
-
int a = 1, b = 2; int* p, *q; p = &a; // modifies object `p` (to point to `a`) q = &b; // modifies object `q` (to point to `b`) *p = 3; // modifies object `a` (pointed to by `p`)
-
Address and pointer types
size_t
: An unsigned integral type that represents sizes- On x86-64, 8 bytes big
- Values 0–18,446,744,073,709,551,615 (0–(2^{64}-1))
- If using
printf
, print with%zu
uintptr_t
: An unsigned integral type that represents addresses- On x86-64, 8 bytes big
- Can safely hold the value of any pointer to an object
- Pointer ↔︎ address conversions
-
int* ptr = ...; uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); // verbose, but clear int* ptr2 = reinterpret_cast<int*>(addr); assert(ptr == ptr2); uintptr_t addr2 = (uintptr_t) ptr; // C-style, less safe
-
Some questions about addresses
- Does every object always need an address?
- Or can the compiler sometimes avoid assigning an address to an object?
- Does every different object need a different address?
- When can distinct objects be assigned overlapping addresses, or the same address?
- Are different address ranges used for different purposes?
- Are there any constraints on the addresses for particular objects?
- Do addresses have any consequences for performance?
- How are complex object types represented in memory?
- Let’s design experiments to test some hypotheses!
Storage duration and lifetime
- Every C++ object has a lifetime
- It is illegal to refer to an object outside its lifetime
- Lifetimes fall into a few categories called storage durations
- Static storage duration: The object survives for the length of the program
- Automatic storage duration: The object survives until its containing function returns
- Dynamic storage duration: The object survives until it is explicitly deleted
Dynamic storage duration
- Advantages
- Can construct objects whose size depends on runtime factors
- A program can use only the amount of memory it needs
- Can build an object in one function, use it in a second, and deallocate it in a third
- Disadvantages
- Memory errors
Implementing dynamic storage duration
- Request chunks of memory (arenas) from the operating system
- Hand out parts of those chunks on request