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

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

Embed Size (px)

Citation preview

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

1

Homework / Quiz

• Exam 2– Solutions Posted– Questions?

• Continuing K&R Chapter 6

• HW6 is on line – due class 22

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

2

Self Referential structs, K&R 6.5

• Look at this binary tree structure (Pg. 139)now

is the

for

all

aid come

men of time

party their togood

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

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!

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

4

Tree of struct tnodes

char *wordint counttnode *lefttnode *right

keyword \0

char *wordint counttnode *lefttnode *rightchar *word

int counttnode *lefttnode *right

……

……

tnode *root

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

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

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

6

Declarations / Prototypes

#include <stdio.h>#include <ctype.h> (see functions in App. B2, pp. 248-249, K&R)#include <string.h> (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 *);

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

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; }

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

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);

}}

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

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];

}

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

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;}

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

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

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

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);

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

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

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

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));

}

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

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;

}

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

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

Free

In UseIn Use

Free FreeIn Use

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

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 blockof memory - even though there is theoreticallysufficient free memory! Memory is fragmented!!

In use Free In use Free In use Free In use

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

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

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

19

Intro to HW6

• Initial structures in allocbuf[]

• Structures after two calls to alloc()

blockl blockl blocklblockr blockr blockr

Inuse 1Inuse 2Free Memory

blockl blockr

Free Memory

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

20

Intro to HW6

• Structures after free call on first block only

• Structures after free call on second block only

blockl blocklblockr blockr

Inuse 1Free Memory

blockl blockl blocklblockr blockr blockr

Free Memory Inuse 2 Free Memory

Note effect of coalesce!

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

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)