Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Homework / Quiz Exam 2 – Solutions Posted – Questions? Continuing K&R Chapter 6 HW6 is on line – due class 22.

Similar presentations


Presentation on theme: "1 Homework / Quiz Exam 2 – Solutions Posted – Questions? Continuing K&R Chapter 6 HW6 is on line – due class 22."— Presentation transcript:

1 1 Homework / Quiz Exam 2 – Solutions Posted – Questions? Continuing K&R Chapter 6 HW6 is on line – due class 22

2 2 Self Referential structs, K&R 6.5 Look at this binary tree structure (Pg. 139) now isthe for all aidcome menoftime partytheirtogood

3 3 Self Referential structs struct tnode { /* the tree node struct */ char *word; /* points to the word at this node */ int count; /* has a count of occurances */ struct tnode *left; /* a word < one at this node */ struct tnode *right; /* a word > one at this node */ }; OK to have a pointer to a struct of same type in its own definition NOT OK to have a struct itself in its own definition!

4 4 Tree of struct tnodes char *word int count tnode *left tnode *right keyword \0 char *word int count tnode *left tnode *right char *word int count tnode *left tnode *right … … … … … … tnode *root

5 5 Self Referential structs Each node is a struct tnode with a string value and a count of occurrences Each node also contains a pointer to a left child and a right child Each child is another struct tnode

6 6 Declarations / Prototypes #include #include (see functions in App. B2, pp. 248-249, K&R) #include (see functions in App. B3, pp. 249-250, K&R) #include “getch.h” #define MAXWORD 100 int getword(char *word, int lim); struct tnode *addtree(struct tnode *, char *); void treeprint(struct tnode *);

7 7 Main program int main( ) { struct tnode *root; /* ptr to root for binary tree*/ char word[MAXWORD]; /* word to get from stdin */ root = NULL; /* initially, no tnodes in tree */ /* OK that root pointer points to NULL initially*/ while (getword(word, MAXWORD) != EOF) /* getword from stdin*/ if (isalpha(word[0])) /* from ctype.h library */ root = addtree(root, word); /* expect not NULL anymore*/ treeprint(root); /* print it out in order */ return 0; }

8 8 treeprint ( ) To print out tree contents in order: void treeprint (struct tnode *p) { if (p != NULL) { treeprint (p->left); printf (%4d %s\n”, p->count, p->word); treeprint (p->right); }

9 9 getword ( ) int getword(char *word, int lim) { int c; char *w = word; while isspace(c = getch())/* skip spaces; c first non-space*/ ; if (c != EOF) *w++=c;/* c might be EOF here (empty word) */ if(!isalpha(c)) {/* c (identifier) starts with alpha*/ *w = '\0'; return c;/* if not, word empty*/ } for( ; --lim > 0; w++) if (!isalnum(*w = getch())) {/* identfier alpha or digits*/ ungetch(*w); break; /* e.g., + might be needed later */ } *w = '\0'; return word[0]; }

10 10 addtree ( ) struct tnode *talloc(void); /* allocate. return ptr to tnode */ char *strdup(char *); /* allocate space, copy word there */ struct tnode *addtree(struct tnode *p, char *w) { int cond; /*for empty tree, root is NULL*/ if (p == NULL) { /* nothing at this node yet */ p = talloc(); /* allocate a new node */ p->word = strdup(w); /* allocate space, copy word there */ p->count = 1; /* count is 1 */ p->left = p->right = NULL; /* this works; see precedence */ } else if ((cond = strcmp(w, p->word)) == 0) /* string.h */ p->count++; /* repeated word, increment count */ else if (cond < 0) /* note cond remembers strcmp above */ p->left = addtree(p->left, w); /* less: go left subtree */ else /* more, go to right subtree */ p->right = addtree(p->right, w); return p; }

11 11 addtree( ) Note, that addtree is recursive. If it adds a node, it might need to add root or any left or right child anywhere down the tree We pass struct tnode *p as first argument, and also pass back the same type - always a pointer to the node at the current recursive nesting level Any time a new node is created: root, p->left or p->right in node above will be set for the FIRST time based on return value from addtree

12 12 addtree ( ) When main calls addtree, the return sets root value each time even if the root already pointed to tnode Allows for possible addition of a pointer to a node Why do we need to return a struct tnode *p when we have struct tnode *p as an argument? Can't we just set it via argument, return void from addtree, and write (in main)? addtree(root, word); instead of root = addtree(root, word);

13 13 addtree ( ) No, root is already a pointer, struct tnode *, but it is the pointer root itself that must be modified To modify root, we would need to declare addtree with a pointer to a struct tnode * as the first arg: void addtree(struct tnode **pptr, char *w) { struct tnode *p = *pptr; Call it from main recursively by invocation: addtree(&root, word); Then, addtree could set the value for root directly *pptr = p; Same is true when adding a left or right child

14 14 talloc ( ) How to write talloc to allocate a tnode and return a pointer. struct tnode *talloc(void) { return (struct tnode *) malloc (sizeof(struct tnode)); }

15 15 strdup ( ) strdup ( ) creates space for a character string, copies a word into it (up to null terminator) and returns the char pointer char *strdup(char *s) { p = (char *) malloc (strlen(s)+1); /* +1 for '\0' */ if (p != NULL) /* if malloc didn’t fail */ strcpy(p, s); /* library function in string.h */ return p; }

16 16 Intro to HW6 Memory model for malloc( ) and free( ) Before any calls to alloc( ): allocbuf: After two calls to alloc( ) and before call to freef( ): allocbuf: After call to freef( ) on first block alloc gave out: allocbuf: Free In Use Free In Use

17 17 Intro to HW6 Fragmentation with malloc( ) and free( ) Before call to alloc( ) for a large memory block: allocbuf: alloc can NOT provide a large contiguous block of memory - even though there is theoretically sufficient free memory! Memory is fragmented!! In useFreeIn useFreeIn useFreeIn use

18 18 Intro to HW6 Not possible to “defragment” allocbuf memory after the fact as you would do for a disk On a disk, the pointers to memory are in the disk file allocation table and can be changed With malloc, programs are holding pointers to memory they own - so can’t be changed!! Can only defragment as blocks are freed by using program

19 19 Intro to HW6 Initial structures in allocbuf[] Structures after two calls to alloc() blockl blockr Inuse 1Inuse 2Free Memory blocklblockr Free Memory

20 20 Intro to HW6 Structures after free call on first block only Structures after free call on second block only blockl blockr Inuse 1Free Memory blockl blockr Free MemoryInuse 2Free Memory Note effect of coalesce!

21 21 Intro to HW6 Four possible states for block being freed –Between two blocks that are still in-use –Above a free block and below an in-use block –Above an in-use block and below a free block –Above a free block and below a free block When freeing a block, coalesce with adjacent free blocks to avoid unnecessary fragmentation of allocbuf (allows alloc to serve later requests for large amounts of memory)


Download ppt "1 Homework / Quiz Exam 2 – Solutions Posted – Questions? Continuing K&R Chapter 6 HW6 is on line – due class 22."

Similar presentations


Ads by Google