1 Plan for today Quick review of previous lecture Array of pointers Command line arguments Dynamic memory allocation (malloc) Structures (Ch 6) Input and Output (Ch 7) 1 Pointers K&R Ch 5 Basics: Declaration and assignment Pointer to Pointer Pointer and functions (pass pointer by value) Pointer arithmetic +- ++ -- Pointers and arrays (5.3) Stored consecutively Pointer to array elements p + i = &a[i] *(p+i) = a[i] Array name contains address of 1 st element a = &a[0] Pointer arithmetic on array (extension) p1-p2 p1<>!= p2 Array as function argument decay Pass sub_array Arrays of pointers Command line argument (program parameter) Pointer to arrays and two dimensional arrays Memory allocation Pointer to functions Pointer to structures IO Previous lecture
2 Problems with pointers int *ptr; /* I m a pointer to an int */ ptr= &a /*I got the address of rate */ *ptr = 5; /* set contents of the pointee a */ int *ptr; /* I m a pointer to an int */ *ptr = 5; /* contents of the pointee is 5*/ segmentation fault (core dumped) ptr is uninitialized. Has some random value but don t know Points to sth unknown, may be your OS! Always make it point to sth! How? 1) int a; ptr =&a; int arr[20]; ptr=arr; 2) ptr = ptr2 assuming ptr2 is good 3 3) ptr = malloc (...) Problems with pointers, another scenario char name[20]; char *name2; int age; double wage; scanf( %s %s %d %f,name,name2,age,wage); printf( input name, name2, age, wage ); while( strcmp(name, xxx ) ). } segmentation fault 4 (core dumped) segmentation fault (core dumped)
3 Pointers K&R Ch 5 Basics: Declaration and assignment Pointer to Pointer Pointer and functions (pass pointer by value) Pointer arithmetic +- ++ -- Pointers and arrays (5.3) Stored consecutively Pointer to array elements p + i = &a[i] *(p+i) = a[i] Array name contains address of 1 st element a = &a[0] Pointer arithmetic on array (extension) p1-p2 p1<>!= p2 Array as function argument decay Pass sub_array Arrays of pointers (5.6) Command line argument Pointer to arrays and two dimensional arrays Memory allocation Pointer to functions Pointer to structures Arrays of Pointers (5.6) Pointers are variables Can be arrayed like others (int, char, double) int * x[3] /* array of 3 integer pointers */ 0 1 2 mnemonic x[i] is a integer pointer (int *) x[i] = &var *x[i] = 4; //set pointee **(x+i) =4; 6
4 Precedence and Associativity p53 Operator Type Operator Associativity Primary Expression Operators () []. -> left-to-right mnemonic Unary Operators Binary Operators * & + -! ~ ++ -- (typecast) sizeof * / % arithmetic + - arithmetic >> << bitwise < > <= >= relational ==!= relational & ^ bitwise bitwise bitwise && logical logical right-to-left left-to-right Ternary Operator?: right-to-left int * x[3] /* array of 3 integer pointers */ char * x[5] /* array of 5 char pointers */ Assignment Operators = += -= *= /= %= >>= <<= &= ^= = right-to-left Comma, /*??? */ left-to-right char (*x)[5] Arrays of Pointers (5.6) Common use: array of char pointers (strings) char * words[]={ apple, cherry, banana }; char words[4][5]={ apple, cherry, banana }; //another words is an array of pointers to char (char *) Each element of words ( words[0], words[1], words[2]) is a pointer to char. 8 0 1 2 words apple cherry banana
5 Another example, initialization char * message[10] = { one, two, three }; 9 Another example, initialization char * message[10] = { one, two, three }; 800 10 char arr[] = four ; message [8] = arr;
6 Arrays of Pointers (5.6) Common use: array of char pointers (strings) char * msg[]={ one, two, three }; Each element of msg (msg[0])is a pointer to char. msg[1] msg +1 *(msg+1) A pointer to two, address of t &msg[1], address of first pointer A pointer to two, address of t printf( s, *(msg+2) + 1 msg[1]) A two *(msg+2) + 1 & of h *( *(msg+2) + 1) h msg[2][1]? h Arrays of Pointers (5.6) Common use: array of char pointers (strings) char * msg[]={ one, two, three }; Each element of msg (e.g., msg[0])is a pointer to char. char **p; p = msg; // = & msg[0] *p? // msg[0] a pointer p+1? // & msg[1] *(p+1)? // *(msg+1) msg[1] p[1] **p ; // msg[0][0] o *(*(p+2)+1) //msg[2][1] h p[2][1]
7 Arrays of Pointers (5.6) Common use: array of char pointers (strings) char * msg[]={ one, two, three }; Each element of msg (e.g., msg[0])is a pointer to char. char **p; p = msg; printf("%s\n", *p ); // msg[0] one printf("%s\n",*(p+1) );// msg[1] two printf("%c\n", **p ); // msg[0][0] printf("%c\n", *(*(p+1)+2) ); //msg[1][2] o printf("%c\n", *(*(p+2)+1 )); //msg[2][1] h 13 printf("%c\n", *(*(p+2)+2) +1 ); Passing an array of pointers to function main(){ char *message[3] = { one, two, three }; printf( %s, message[1]); // two print_message(message, 3); } void print_message(char *p[], int n){ int count; for (count=0; count<n; count++) printf( %s, p[count]); } 14 // *(p+count) Need to provide!!!
8 Passing an array of pointers to function main(){ char *message[3] = { one, two, three }; printf( %s, message[1]); // two print_message(message, 3); } Decay? Address of pointer void print_message(char **p, int n){ int count; for (count=0; count<n; count++) printf( %s, *(p + count) ); } 15 // p[count] Need to provide!!! Advantage of Pointer Arrays (vs. 2D array) char *name[] = {"Illegal month", "Jan", "Feb", "Mar" Ragged array sizeof(name)? 8*4=32 Total memory space? 32 + 14 + 4 + 4 + 4 char aname[][15]={"illegal month","jan", "Feb", "Mar" 16 sizeof (aname)? 15*4=60
9 char planets[][8] = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"}; char *planets[] = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"}; 17 Advantage of Pointer Arrays (vs. 2D array) int a[10][20]; int *b[10]; a: 200 int-sized locations have been set aside. b: only 10 pointers are allocated and not initialized; initialization must be done explicitly. Assuming each element of b points to an array of 20 elements, total size = 200 integers + 10 pointers. Advantage of b: 1. the rows of the array may be of different lengths (saving space). 2. Another advantage? Swap rows! 18
10 char planets[][8] = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"}; How to swap? plants[0] = plants[1]??? strcpy(tmp,p[0]) strcpy(p[0],p[1]) strcpy(p[1],tmp) How to swap? 19 char *planets[] = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"} Efficient manipulation of strings char *lines[]={ dog, apple, zoo, program, merry }; char * tmp = lines[0]; /* dog vs. apple */ lines[0] = lines[1]; // two char pointers lines[1] = tmp; tmp = lines[2]; /* zoo vs. merry */ lines[2] = lines[4]; // two char * pointers lines[4] = tmp; Exchange pointers (addresses) Not real data 1000 1000 1000 20 20 20 1000 20 20 Exchange two addresses, That s it!!
11 public static void main(string[] args) Command-Line Arguments (5.10) Up to now, we defines main as int main() Usually it is defined as int main(int argc, char *argv[]) argc is the number of arguments (including program name) argv is an array containing the arguments. argv[0] is a pointer to a string with the program name. So argc is at least 1. (Java?) Optional arguments: argv[1] ~~ argv[argc-1] 21 argv[argc] is a NULL pointer. Command line arguments indigo 421 % a.out hello, world argv[0]: a.out argv[1]: hello, argv[2]: world 0 1 2 3 args argc = 3 0 1 2
12 Command-Line Arguments (cont.) main( int argc, char *argv[] ) { int i; printf( Number of arg=%d\n, argc ); for( i=0; i<argc; i++ ) printf( %s\n, argv[i] ); } *(argv+i) > a.out Number of arg=1 argv[0]: a.out 23 >a.out how are you Number of arg=4 argv[0]: a.out argv[1]: how argv[2]: are argv[3]: you >a.out how are you Number of arg=3 argv[0]: a.out argv[1]: how argv[2]: are you Array of points vs. pointers to whole Array char *arr[3]; /* array of 3 pointers */ 0 1 2 arr h i \0 arr+1? char (*arr)[3]; /* pointer to a 3 char array */ arr h i \0 arr+1? 24
13 Summary decay char a [20] char * p char *a [20] char ** p p p+1 char a [ ][8]? char (*p)[8] p p+1 p+2 25 26
14 Pointers K&R Ch 5 Basics: Declaration and assignment Pointer to Pointer Pointer and functions (pass pointer by value) Pointer arithmetic +- ++ -- Pointers and arrays (5.3) Stored consecutively Pointer to array elements p + i = &a[i] *(p+i) = a[i] Array name contains address of 1 st element a = &a[0] Pointer arithmetic on array (extension) p1-p2 p1<>!= p2 Array as function argument decay Pass sub_array Arrays of pointers Command line argument Pointer to arrays and two dimensional arrays Memory allocation Pointer to functions Pointer to structures IO Previous lecture Done Dynamic memory allocation scenario / motivation 1 When we define an array, we allocate memory for it int arr[20]; sets aside space for 20 ints This space is allocated at compile-time (i.e. when the program is compiled) 28
15 Dynamic memory allocation scenario / motivation 1 What if we do not know how large our array should be? In other words, we need to be able to allocate memory at run-time (i.e. while the program is running) How? scanf( %d, &n); int my_array[n]; /* not allowed in ANSI-C */ 29 Fortunately, C supports dynamic storage allocation: the ability to allocate storage during program execution. Using dynamic storage allocation, we can design data structures that grow (and shrink) as needed. The <stdlib.h> header declares three memory allocation functions: malloc Allocates a block of memory but doesn t initialize it. calloc Allocates a block of memory and clears it. realloc Resizes a previously allocated block of memory. These functions return a value of type void * (a generic pointer). 30
16 malloc() 1000 1001 1002 1003 1004. stdlib.h defines: void * malloc (int n); allocates memory at run-time returns a void pointer to the memory that has at least n bytes available (just allocated for you). Address of first byte Can be casted to any type 31 malloc() #include <stdlib.h> int main() { int *x; x = (int *) malloc(4); /*segmentation without this line */ } *x = 52; printf( %d\n, *x); segmentation fault (core dumped) 32
17 malloc() #include <stdlib.h> int main() { int *x; x = (int *) malloc(4); /*segmentation without this line */ *x = 52; printf( %d\n, *x); } Note: type conversion (cast) on result of malloc x = malloc(4); also works. Will convert 33 sizeof A better approach to ensure portability int *x; x = (int *) malloc( 4 ); x = (int *) malloc( sizeof(int) ); Note: a variable or lvalue argument can be surrounded by (), so: sizeof(x) works for both types and variables 34
18 NULL malloc() returns NULL when it cannot fulfill the request, i.e., memory allocation fails <stdio.h> defines macro NULL NULL == 0 as a pointer == points to nothing p = malloc(10000); if (p == NULL) { /* allocation failed; take appropriate action */ } else 35 if ( (p = malloc(10000)) == NULL) { /* allocation failed; take appropriate action */ }else. malloc() 7 #include <stdlib.h> -1 int main() { scanf( %d, &n); p +1 p +2 int * p = (int *) malloc(n * sizeof(int)); ( if (p == NULL) exit(0); 36 *p = 1; // p[0] = 1 *(p+1) = 2; // p[1]= 2 p[2] = 12; // *(p+2)= 12
19 calloc() vs. malloc() void *calloc(int n, int size); calloc(x, y) is pretty much the same as malloc(x * y) except malloc does not initialize memory calloc initializes memory content to 0 (zer0) 0 0 0 0 0 0 37-1 free() malloc, calloc and the other memory allocation functions obtain memory blocks from a storage pool known as the heap. A block of memory that s no longer accessible to a program is said to be garbage. A program that leaves garbage behind has a memory leak. Some languages (Java!!!) provide a garbage collector that automatically locates and recycles garbage, but C doesn t. 38
20 Memory Leaks int *x; x = (int *) malloc( 20 ); x = (int *) malloc( 30 ); The first memory block (20 bytes) is lost for ever. MAY cause problems (exhaust memory). 39 free() Instead, each C program is responsible for recycling its own garbage by calling the free function to release unneeded memory. void free(void *ptr); frees memory we previously allocated, tells the system we no longer need this memory and that it can be reused address in ptr must have been returned from either malloc, calloc or realloc. 40 p = malloc( ); free(p);
21 realloc() resize a dynamically allocated array. char *ptr; ptr = malloc(20); ptr = realloc(ptr,50); void *realloc(void *ptr, int size); ptr must point to a memory block obtained by a previous call of malloc, calloc, or realloc. size represents the new size of the block, which may be larger or smaller than the original size. realloc(null, n) behaves like malloc(n). realloc (ptr, 0) behaves like free(prt), as it frees the memory block. 41 Better to check the results! #include<stdio.h> #include<stdlib.h> main() { int *a, i, n; printf( Input an array size ); scanf( %d, &n); if ((a = (int*)calloc(n, sizeof(int)) == NULL) exit(0); /* else, a already got the address from calloc */ a[0] = 5; *(a+1) = 30; for(i=2; i<n; i++) scanf( %d, &a[i]); // scanf( %d, a+i); printf( the first element is %d\n, a[0]); free(a); } 42
22 More on memory allocation We know the syntax But when to use it????? When need to allocate at run time, of course What else? Another feature of malloc -- request for heap space! 43 Whenever you need to access its pointee Ask yourself: Have you done one of the following 1. ptr = &var. /* direct */ var must not arr[20]; ptr=arr;variable 2. ptr = ptr2 /* indirect */ 3. ptr = (..)malloc(...) You do need to do one of above for: *ptr = var; var = *prt; ptr[2] = var scanf( %s, ptr) strcpy(ptr, hello ) strcat(ptr, hello ) fgets(ptr,.) 44
23 When to use malloc? When you need to allocate memory in run time, of course When you need memory space throughout the program running 1. ptr = &var. /* direct */ if var is a local variable in function 2. ptr = ptr2 /* indirect */ if ptr2 points to a local variable 3. ptr = (..)malloc(...) correct choice! var is in stack. Not in heap. 45 46 ; What is wrong here??
24 Stack vs. heap Local (stack) memory, automatic Allocated on function call, and variables deallocated automatically when creating function exits Dynamic heap memory The heap is an area of memory available to allocate areas ("blocks") of memory for the program. What I need! Not deallocated when function exits! 47 Request a heap memory: malloc/calloc in C, new in Java free() to deallocated in C, garbage collection in Java Stack vs. heap Local (stack) memory, automatic Allocated on function call, and deallocated automatically when function exits Dynamic heap memory The heap is an area of memory available to allocate areas ("blocks") of memory for the program. Not deallocated when creating function exits Request a heap memory: malloc / calloc / realloc in C new in C++ and Java o Student s = new Student(); What I need! 48 Deallocate from heap memory: free() in C, delete in C++ garbage collection in Java
25 (stack) (stack) (stack) 49 50 ; i is in stack -- deallocated when function exits!!!
26 solution ; 51 Pointers K&R Ch 5 Basics: Declaration and assignment Pointer to Pointer Pointer and functions (pass pointer by value) Pointer arithmetic +- ++ -- Pointers and arrays (5.3) Stored consecutively Pointer to array elements p + i = &a[i] *(p+i) = a[i] Array name contains address of 1 st element a = &a[0] Pointer arithmetic on array (extension) p1-p2 p1<>!= p2 Array as function argument decay Pass sub_array Arrays of pointers Command line argument Pointer to arrays and two dimensional arrays Memory allocation Pointer to functions Pointer to structures IO reviewed Done