C (and C++) Pointers April 4, 2019
Memory Layout RAM is a very long array of bytes Each byte of memory has a unique address The address space is separated into regions Separation is not (generally) restricted April 4, 2019
Memory Layout “Text” (Code) Segment - your program A.K.A. The “Code” segment Executable code text April 4, 2019
Memory Layout Initialized Data Segment Global & Static Variables Must be initialized char s[] = “hello world”; int debug = 1; initialized data April 4, 2019
Memory Layout Uninitialized Data Segment (BSS Segment)* Global & Static Variables Not initialized Initialized to ‘0’ int debug; int counter = 0; static int i; uninitialized data (bss) *block started by symbol - Ancient assembler reference April 4, 2019
Memory Layout Heap – dynamically allocated memory malloc, realloc, and free (C) new, delete (C++) heap *block started by symbol - Ancient assembler reference April 4, 2019
Memory Layout Stack – “function memory” Program stack Stack register Stack frame Return location Register values Passed variables Return values Variables in a function stack *block started by symbol - Ancient assembler reference April 4, 2019
Pointers A variable that stores a memory address Pointers to different types (C & C++): int *, double *, float *, char *, void * Different OS (16b, 32b, 64b) have different sizes of pointers Pointers are not type checked References allow you to give multiple names to a memory location (C++): int &, double &, float &, char &, void & Just like any other variable int num = 4; // the variable ‘num’ is at memory address 0x1234 int *addressOfNum = &num // 0x1234; int &refersToNum = *(&num); // == 4. Changing num or refersToNum has the same result April 4, 2019
Pointers In variable declaration * declares a pointer: Confusing because the notation changes meaning In variable declaration * declares a pointer: int *pointerToInteger; In the body of the code * means “points to”: int value = *pointerToInteger; In variable declaration & declares a reference: int &refersToAnother = *pointerToInteger; In the body of the code & means “the address of”: char *pointerToString = &”ABC1323”; April 4, 2019
Pointers Example 1 Output: int main() { /* Pointer of integer type, this can hold the * address of a integer type variable. */ int *p; int var = 10; /* Assigning the address of variable var to the pointer * p. The p can hold the address of var because var is * an integer type variable. p= &var; printf("Value of variable var is: %d", var); printf("\nValue of variable var is: %d", *p); printf("\nAddress of variable var is: %p", &var); printf("\nAddress of variable var is: %p", p); printf("\nAddress of pointer p is: %p", &p); return 0; } Output: Value of variable var is: 10 Address of variable var is: 0x7fff5ed98c4c Address of pointer p is: 0x7fff5ed98c50 Pointers Example 1 April 4, 2019
Pointers Example 2 Output: Math can be done on pointers int main() { /* Pointer of uchar type, this can hold * the address of (i.e. points to) a byte. */ unsigned char *p; int var = 1656543; // 4 bytes – 0x001946DF p = (unsigned char *)(&var); printf("Value of p is: %p", p); printf(“\nValue of var is: %d", var); printf("\nValue of *p is: %p", *p); ++p; printf("\nValue of p is: %p", &p); return 0; } Example 2 Output: Value of p is: 0x7fff5ed98c4c Value of var is: 0x001946DF Value of *p is: 0x00 Value of *p is: 0x19 Value of *p is: 0x46 Value of *p is: 0xDF Value of p is: 0x7fff5ed98c50 Math can be done on pointers ++ & -- by the size of the type of pointer (u)char = 1 (u)int = 4 (depending on the OS) void * is a special case April 4, 2019
Pointers Example 2 Output: int main() { /* Pointer of uchar type, this can hold * the address of (i.e. points to) a byte. */ unsigned char *p; int var = 1656543; // 4 bytes – 0x001946DF p = (unsigned char *)(&var); printf("Value of p is: %p", p); printf(“\nValue of var is: %d", var); printf("\nValue of *p is: %p", p[0]); printf("\nValue of *p is: %p", p[1]); printf("\nValue of *p is: %p", p[2]); printf("\nValue of *p is: %p", p[3]); printf("\nValue of p is: %p", &p); return 0; } Example 2 Output: Value of p is: 0x7fff5ed98c4c Value of var is: 0x001946DF Value of *p is: 0x00 Value of *p is: 0x19 Value of *p is: 0x46 Value of *p is: 0xDF Value of poiter p is: 0x7fff5ed98c50 Arrays are just convenient notation for pointers Multi-dimensional arrays are “pointers to pointers”: **pp April 4, 2019
Pointers to Pointers Can be chained int main() { int rows = 10; int columns = 15; int **array2d = (int **)::malloc(rows * ::sizeof(int *)); for (int i=0; i<rows; i++) { array2d[i] = (int *)::malloc(columns * ::sizeof(int)); } return 0; ------------------------------------------------------------ array2d[0] = (int *)::malloc(rows * columns * ::sizeof(int)); April 4, 2019
Pointers Passing parameters to functions Pass by value Pass by reference void swap1(int i, int j) { int tmp = i; i = j; j = tmp; } void swap2(int& i, int& j) { int tmp = i; i = j; j = tmp; } void swap3(int *i, int *j) { int tmp = *i; *i = *j; *j = tmp; } April 4, 2019
Pointers Function Pointers Function Pointers #include <stdio.h> // A normal function with an int parameter // and void return type void funct(int a) { printf("Value of a is %d\n", a); } int main() // funct_ptr is a pointer to function funct() void (*funct_ptr)(int) = &funct; /* The above line is equivalent of * the following two: void (*funct_ptr)(int); funct_ptr = &funct; */ // Invoking funct() using funct_ptr (*funct_ptr)(10); return 0; Function Pointers Function Pointers April 4, 2019