Homework / Exam • Finishing K&R Chapter 5 today – Skipping sections 5.7-5.9 for now – Not covering section 5.12 • Starting K&R Chapter 6 next • Continue HW5 – Due at start of class 17 • Exam Class 18 – Through end of K&R 6.4 plus MAKE 1 Using malloc( ) and free( ) • To get a pointer p to a block of memory that is n characters in length, program calls p = malloc(n); • When it is finished with that memory, the program returns it by calling free(p); • Sounds simple, huh? • It is NOT so simple! 2 Using malloc( ) and free( ) • malloc returns a pointer to void (void *) that is the address of a memory block of n bytes • If you need a pointer to n of a specific type, you must request a memory block in size of the type and cast pointer returned by malloc int *p; p = (int *) malloc(n * sizeof(int)); • Contents of memory block are NOT initialized! 3 Using malloc and free • If it can not provide the requested memory, malloc returns a NULL pointer value • If you dereference a NULL pointer to access memory System Crash!! • Always check to be sure that the pointer returned by malloc is NOT equal to NULL • If pointer is NULL, code must take appropriate recovery action to handle lack of memory 4 Using malloc and free • Call to free does not clear the program’s pointer to the memory block, so it is now a “stale” pointer • If program uses pointer after free( ) by accessing or setting memory via pointer, it could overwrite data owned by another program System Crash! • If program calls free again with the same pointer, it releases memory possibly owned by a different program now System Crash! • SHOULD set pointer to NULL after calling free( ) 5 Using malloc and free • However, if you set the pointer to a memory block to NULL before calling free, you have caused the system to lose the memory forever • This is called a memory leak!! • If it happens enough times System Crash!! • MUST not clear or overwrite a pointer to a memory block before calling free!! 6 Pointers to Functions • What is &foobar in the following code fragment? int main () { … &foobar … } int foobar (void) { /* some code here */ } 7 Pointers to Functions • &foobar is the address of the entry point to the function foobar - in code space, not in data space int main () { … &foobar … /* pointer to foobar code’s entry point */ } int foobar (void) { /* some code here */ } 8 Pointers to Functions • Why would we need the address of the entry point to foobar and how would we use it? • We can pass the address of foobar as an argument to another function that needs to call foobar: … result = function (i, j, &foobar); … int foobar (void) { /* some code here */ } 9 Pointers to Functions • Define, initialize, and use a pointer to a function /* Define the function pointer fooptr */ int (*) (void ) fooptr; /* type is “function pointer” */ /* set function pointer fooptr = address of foobar */ fooptr = &foobar; /* Call the function foobar via the pointer fooptr */ result = (*fooptr) (void); /* Why first parens? */ 10 Pointers to Functions, K&R 5.11 • Function prototype with a pointer to a function void qsort ( … , int (*comp) (void *, void *)); • Function call passing a pointer to a function and casting the data types of the argument variables qsort( … , (int (*) (void *, void *)) strcmp); /* strcmp is defined with char * argument variables*/ /* but qsort needs a function with void * as arguments */ • qsort calling the function via passed the pointer if ((*comp) (v[i], v[left]) < 0) … • Note: qsort here is NOT same as standard library qsort, but it uses the same type of function pointer argument! 11 structs, K&R 6 • A struct is a collection of variables, possibly of different types, grouped under a single name for common reference as a unit. struct point { /* with optional tag */ int x; /* member x */ int y; /* member y */ } pt, q; /* variable names */ or struct { /* w/o optional tag */ int x, y; /* two members */ } pt, q; /* variable names */ 12 structs • The defined struct point is like a new “type” • With the tag, point, can declare other variables: struct point pt1, maxpt = {320, 200}; • Reference to struct members: pt1.x = 320; pt1.y = 200; /* alternate init */ printf("(%d, %d)\n", pt1.x, pt1.y); /* prints out as (320, 200) */ 13 structs • Defining a struct inside a struct (nesting). struct rect { struct point pt1; /* lower left */ struct point pt2; /* upper right */ }; struct rect box;/* declare box as a rect */ 14 structs • pt1 is lower left hand corner of box • pt2 is upper right hand corner of box: box.pt1.x < box.pt2.x box.pt1.y < box.pt2.y box.pt2.y y box.pt1.y box.pt1.x x box.pt2.x 15 structs /* Find area of a rectangle */ int area = rectarea (box); … int rectarea (struct rect x) { return (x.pt2.x - x.pt1.x) * (x.pt2.y - x.pt1.y); } 16 structs • Memory allocation for structs – Two point structs pt1 and pt2 pt1 pt2 pt1.x pt1.y pt2.x pt2.y – One rect struct box containing two point structs box pt1 pt2 pt1.x pt1.y pt2.x pt2.y 17