1. Pointers and Addresses
|
|
Pointers and Addresses |
|
Pointers and Addresses |
– Pointer: memory address of a variable
– Address can be used to access/modify a variable from anywhere
– Extremely useful, especially for data structures
– Well known for obfuscating code |
|
Let us begin with a simplified picture of how memory is organized.
|
|
– The unary operator & gives the address of an object, so the statement |
|
|
Physical Memory |
|
Physical resources where data can be stored and accessed by your computer |
– cache, RAM, hard disk, removable storage |
Physical memory considerations |
– Different sizes and access speeds
– Memory management – major function of OS
– Optimization – to ensure your code makes the best use of physical memory available
– OS moves around data in physical memory during execution
– Embedded processors – may be very limited |
|
Virtual Memory |
|
Abstraction by OS, addressable space accessible by your code |
How much physical memory do I have? |
– Answer: 2 MB (cache) + 4 GB (RAM) + 1 TB (hard drive) + ... |
How much virtual memory do I have? |
– Answer: <4 GB (32-bit OS), typically 2 GB for Windows, 3-4 GB for Linux |
Virtual memory maps to different parts of physical memory |
Usable parts of virtual memory: stack and heap |
– stack: where declared variables go
– heap: where dynamic memory goes |
|
Addressing Variables |
|
Every variable residing in memory has an address! |
What doesn’t have an address? |
– register variables
– constants/literals/preprocessor defines
– expressions (unless result is a variable) |
How to find an address of a variable? The & operator |
int n= 4;
double pi = 3.14159;
int *pn = &n; /* address of integer n */
double *ppi = π /* address of double pi */
|
|
|
Dereferencing Pointers |
I have a pointer – now what? |
Accessing/modifying addressed variable: dereferencing/indirection operator * |
/* prints "pi = 3.14159\n " */
printf ( "pi = %g\n" , *ppi );
/* pi now equals 7.14159 */
*ppi = *ppi + *pn ;
|
|
Dereferenced pointer like any other variable |
null pointer, i.e. 0(NULL): pointer that does not reference anything |
|
Casting Pointers |
|
Can explicitly cast any pointer type to any other pointer type |
ppi =(double *)pn; /* pn originally of type (int *) */
|
|
Implicit cast to/from void * also possible |
Dereferenced pointer has new type, regardless of real type of data |
Possible to cause segmentation faults, other difficult-to-identify errors |
– What happens if we dereference ppi now? |
|