Instructions: This is a closed book, closed note exam. Calculators are not permitted. If you have a question, raise your hand and I will come to you. Please work the exam in pencil and do not separate the pages of the exam. For maximum credit, show your work. Good Luck! Your Name (please print) This exam will be conducted according to the Georgia Tech Honor Code. I pledge to neither give nor receive unauthorized assistance on this exam and to abide by all provisions of the Honor Code. Signed 1 2 3 4 25 25 25 25 1 1
Problem 1 (25 points) Hash Tables Consider an open hash table composed of a four-bucket table, with each bucket containing a variable length list. Each list entry has three slots <key, value, next> corresponding to the three word groupings in the entries section. The hash function is key mod four. Inserted entries are appended to the end of a bucket list. The initial state of the hash table is shown. List elements as allocated by malloc are shown in the figure. The symbol to the left of each list element (A, B, C,...) is the address returned by malloc. Entries that are freed are maintained in a last-in-first-out (LIFO) free list. Execute the access trace shown in the table below. For ease of representation, you may use the allocated blocks in any order. Show pointers both by their (symbolic) value, and with an arrow. If a value changes, cross it out and place the new value to the right. If a pointer changes, also place an x on the corresponding arrow, and draw the new arrow. Buckets (Hash Anchor Table) 3 2 1 A B A 19 555 D G B 38 333 E H C F I Hash Table Access Trace # op key value # op key value 1 insert 27 111 5 remove 38 n/a 2 insert 32 222 6 remove 27 n/a 3 insert 19 444 7 insert 22 888 4 insert 43 777 8 insert 16 999 2
Problem 2 (3 parts, 25 points) Consider a hash table that is implemented using the following struct definitions. #define NUMBUCKETS 13 typedef struct Entry { int Key; int Value; struct Entry *Next; Entry; Associative Set Performance typedef struct { Entry *Buckets[NUMBUCKETS]; int Size; HashTable; Suppose the entries are maintained in a sorted linked list in order of increasing key values in each bucket. Part A (8 points) Complete the C function Find_Key that efficiently searches the hash table for an entry corresponding to a specified key. It should return a pointer to the matching Entry if Key is found or return NULL if Key is not found in the hash table. Entry *Find_Key(HashTable *HT, int Key) { Entry *ThisEntry; int Index; int Hash(int Key); /* function prototype for hash function */ Part B (1 points) Suppose a hash table created using the structs above contains 312 entries total and the entries are evenly distributed across the hash table buckets. Assume that computing the hash function takes an average of two operations and comparing two keys takes an average of twelve operations. Suppose that two thirds of keys looked up are found in the hash table and one third are not found. How many of these operations would be required for the average lookup in the hash table if the bucket list is unsorted versus sorted? (Show work.) Number of operations when each bucket list is unsorted: Number of operations when each bucket list is sorted: Part C (7 points) Suppose the hash table automatically resizes (with the same 312 entries and found key probabilities) so that the average access time becomes 7 operations. How many hash table buckets are being used, assuming each bucket contains an unsorted list of entries? (Show work.) New number of buckets: 3
Problem 3 (5 parts, 25 points) Heap Management Below is a snapshot of heap storage. Values that are pointers are denoted with a $. The heap pointer is $6152. The heap has been allocated contiguously beginning at $6, with no gaps between objects. addr value addr value addr value addr value addr value addr value 6 12 632 8 664 $62 696 8 6128 616 64 24 636 68 668 4 61 $648 6132 4 6164 68 4 64 1 672 2 614 16 6136 632 6168 612 16 644 12 676 16 618 12 614 6172 616 12 648 16 68 128 6112 152 6144 24 6176 62 $64 652 632 684 64 6116 8 6148 618 624 $68 656 $61 688 4 612 16 6152 6184 628 $648 66 4 692 68 6124 24 6156 6188 Part A (8 points) Suppose the stack holds a local variable whose value is the memory address $664 and register $5 holds the address $68. No other registers or static variables currently hold heap memory addresses. List the addresses of all objects in the heap that are not garbage. Addresses of Non-Garbage Objects: Part B (5 points) Create a free list by scanning the heap memory for garbage, starting at address 6 and placing objects on the free list so that a first-fit allocation strategy will also always produce the best-fit. Free List: Part C (3 points) Based on the free list created in part B, if an object of size 27 bytes is allocated, what address will be returned using a first-fit allocation strategy? How many bytes of slack (if any) will result? Address: Slack: Part D (3 points) Based on the free list created in part B, if an object of size 16 bytes is allocated, what address will be returned using a best-fit allocation strategy? How many bytes of slack (if any) will result? Address: Slack: Part E (6 points) If the local variable whose value is the address $664 is popped from the stack, which addresses will be reclaimed by each of the following strategies? If none, write none. (You need not list addresses already on the free list from part B.) Reference Counting: Mark and Sweep: Old-New Space (copying): 4
Problem 4 (6 parts, 25 points) Dynamic Allocation on Heap Suppose you are developing a path planning application for an autonomous aerial vehicle. Complete the following C code by following the steps below: typedef struct WayPoint { double Altitude; float Longitude; float Latitude; struct WayPoint *Next; WayPoint; WayPoint *Path = NULL; void Add_WayPoint(float La, float Lo, double A){ ; /* part A*/ ; /* part B*/ if ( ){ /* part D */ printf( Error: Insufficient space. ); exit(1); ; /* part F*/ ; /* part F*/ Part A (3 points) Add a local variable called NewPoint that is a pointer to a WayPoint object. Part B (6 points) Allocate space for a WayPoint structure using malloc and make NewPoint point to the object allocated. Be sure to include appropriate type casting to avoid type errors. Part C (3 points) How many bytes are allocated in Part B for the WayPoint structure, excluding its size header? Assume a 32-bit system. bytes Part D (4 points) Fill in the test for whether malloc found enough space which controls the print statement. Part E (3 points) Initialize the fields (Altitude, Longitude, Latitude) of the newly allocated WayPoint object to the values of the 3 input parameters (A, Lo, La, respectively). Part F (6 points) Push the newly allocated WayPoint object onto the front of the list of WayPoint objects pointed to by the global variable Path. 5