 # 1 Pointers A pointer variable holds an address We may add or subtract an integer to get a different address. Adding an integer k to a pointer p with base.

## Presentation on theme: "1 Pointers A pointer variable holds an address We may add or subtract an integer to get a different address. Adding an integer k to a pointer p with base."— Presentation transcript:

1 Pointers A pointer variable holds an address We may add or subtract an integer to get a different address. Adding an integer k to a pointer p with base type t will make the value of p equal to p+k*sizeof(t) Example: int *ptr; int arr = {1,2,3,4}; ptr = arr + 2; // equivalent to ptr = &(arr);

2 Pointers A pointer variable holds an address We can access the contents at that address by using the dereferencing operator, * Do not confuse this with the multiplication operator or with the asterisk used in the pointer's declaration. Example: int *pum, number; pnum = & number; *pnum = 16; cout << number << endl; // this prints 16 NEVER dereference an uninitialized pointer

3 Pointers & functions Pointers allow us to implement pass by reference. void swap(int &a, int &b) { int temp = a; a = b; b = temp; } int main () { int x = 3, y = 5; swap(x,y); return 0; } void swap(int *a, int *b) { int temp =* a; *a = *b; *b = temp; } int main () { int x = 3, y = 5; swap(&x, &y); return 0; }

4 Pointers & functions Function arguments that are pointers copy an address to the formal parameters Dereferencing the formal parameter lets us modify the value pointed to by the pointer. But changing the pointer itself NEVER changes the actual parameter Example 1: int main () { int x, *px; px = &x; initialize(px); return 0; } void initialize (int *ptr) { *ptr = 34; } here x has become 34

5 Pointers & functions Function arguments that are pointers copy an address to the formal parameters Dereferencing the formal parameter lets us modify the value pointed to by the pointer. But changing the pointer itself NEVER changes the actual parameter Example 2: int main () { int x, *px; px = &x; initialize(px); return 0; } void initialize (int *ptr) { *ptr = 34; ptr++; } here x has become 34 but px is unchanged.

6 Pointers & functions Be very careful with functions that return pointers. Make certain that the pointer points to something valid on return and that space has been properly allocated. Example: int * func () { int x, *p; x = 10; p = &x; return p; } int main () { int *ptr ; ptr = func(); cout << *ptr << endl; return 0; } This program will print out garbage. Why? p and x are local variables, statically stored in func()'s stack frame. They "disappear" on exit from func(), so *ptr cannot contain the value of x.

7 More on pass by reference When an argument is passed by value, enough memory must be allocated for a copy of that argument. This may slow down our program if the argument is a large object. The solution is to pass it by reference. HOWEVER, we may not want to allow the function to modify the value of the argument. In that case, we must use the keyword const to specify that the argument cannot be changed. This can be done with references, arrays and pointers.

8 More on pass by reference Example 1: struct bigTypeT {... }; void func (const bigTypeT &arg) { // arg cannot be modified } int main () { bigTypeT arg; func(arg); return 0; }

9 More on pass by reference Example 2: void func (const int arr[]) { // arr cannot be modified } int main () { int arr; func(arr); return 0; }

10 More on pass by reference Example 2: void func (const int *ptr) { // *ptr cannot be modified // ptr can be modified but this will have no effect in main() // since ptr is local to func() } int main () { int *pnum, x; pnum = &x; func(pnum); return 0; }

11 Pointers vs. arrays The name of an array represents the address where the array begins. In other words, the name of an array is a pointer HOWEVER, it is a constant pointer. Pointer variables allow greater flexibility int numbers, list; numbers = list; ILLEGAL!

12 Pointers vs. arrays The size of an array must be specified at compile- time and is constant. Pointers allow greater flexibility: we may use pointers to create array-like structures whose size is determined dynamically. Goal : allocate a chunk of memory (size determined at run time) get its address Tool: the function new allocates space The function delete deallocates space that was allocated using new

13 Dynamic allocation Example 1: allocate memory to hold one integer int *pnum; // Declare pointer pnum = new int; // new allocates 4 bytes and returns // the address at that location. The // address is assigned to pnum *pnum = 32; delete pnum;// ALWAYS deallocate dynamically // allocated space to avoid memory leaks

14 Dynamic allocation Example 2: allocate memory to hold one integer and initialize the integer to 32 int *pnum; pnum = new int(32); cout << *pnum;// This prints 32 delete pnum;// ALWAYS deallocate dynamically // allocated space to avoid memory leaks

15 Dynamic allocation Example 3: allocate memory to hold several integers. int *pnums; cout << "How big an array do you want? "; cin >> size; pnums = new int [ size ] ; // note the brackets. // This allocates size*4 bytes for (int i = 0; i < size; i++) *(pnums+i) = 0;// This initializes all elements of the // dynamic array to zero. delete pnums;// ALWAYS deallocate dynamically // allocated space to avoid memory leaks

16 NULL pointers NULL represents a special location in memory that is guaranteed to NOT contain valid data Dereferencing a NULL pointer will cause a segmentation fault. Programmers often initialize pointers to NULL to "catch" any unintended dereferencing of a pointer that does not contain valid data. In some compilers, new returns NULL if it fails to allocate memory.

17 delete Never try to deallocate the same memory twice Example: int *pnum, *pcopy; pnum = new int(32); pcopy = pnum; delete pnum; delete pcopy; // ERROR! This space has already been deallocated

18 delete The argument to delete should always be the address where the allocated space begins. Example: int *pnum, *pcopy; pnum = new int(32); pcopy = pnum; pnum ++; delete pcopy; // CORRECT! delete pnum; // WRONG! pnum does not point to the beginning of // the allocated space any longer.