Remember to create a new directory in your repository for this lab. (Refer to previous labs for how if you have forgotten)
First answer the questions in lab7questions.html.
Second, read through the warmup exercises so you are ready to begin in class.Valgrind is a memory mismanagement detector. It shows you memory leaks, deallocation errors, etc. Actually, Valgrind is a wrapper around a collection of tools that do many other things (e.g., cache profiling); however, here we focus on the default tool, memcheck. Memcheck can detect the following things that are useful to you right now:
Click here for a nice example with explanation for how to use valgrind and interpret its results.
You can use valgrind if you log into the main cs department computers:
ssh cnetid@linux.cs.uchicago.eduYou can check out your repository there, compile it, and test it. You may use vim to edit your code there.
During this week, you will create some code that will be used in your project in the next two weeks. These exercise structures, trees, and function pointers.
As you know, there are two sides to implementing data structures - the data structure itself and what is being held in the data structure.
Problem 1: memory struct and functions
You will first add code for the struct that will be held in the binary search tree. As you know, to use a binary search tree, the struct being stored needs to provide a compare function for insertion. The memory struct represents available memory blocks in the operating system. It contains two fields of unsigned int, representing memory address and size.
Look at memory.h for more information about the memory struct and the necessary functions to implement. You will be implementing them across the warmup and hw. We are having you finish the minimal set to test the BST - then, in the hw, you'll complete it.
You need to implement one compare function. For the warmup, complete memory_addr_cmp, which compares two memory structs by their addresses.
This function takes two arguments, const void* x and const void* y, you will need to cast both of them to type "memory*", and make comparisons. If x is less than y, return -1. If x is greater than y, return 1. If they are equal, return 0;
Problem 2: binary search tree
You are writing several binary search tree functions (bst). Look in bst.h for the overall design of the bst. Note, in particular, that there are two separate structus - the node struct that describes information for a single node in the tree, and a bst struct, that holds the root pointer and a function pointer to the comparison function being used for this tree. When you first create the tree, you pass in the comparison function, and this will be used for all functions that need it thereafter. Therefore, after that, you don't need to specify the comparison function to bst-level functions. The stored function pointer is then passed to the node-level functions.
Begin with allocation and initialization functions for both bst and node.Think very carefully about the order in which you will implement these. Specifically, what is the minimum number of functions you need to implement in order to fill and print out a bst. You should be able to print the memories of the bst in ascending order with function memory_print and bst_inorder_traversal. Choose the simplest functions that will give you this functionality.
You are not expected to complete this in lab.
A program like this, that takes in a lot of data, is exceedingly annoying to test through command-line arguments or hard-coded tests within the code. Instead, what you would like is to have a file of words that can be opened and read.
For files that are not in a strict format, the paired functions fgets and strtok are functions that work every time. Once you learn to use them, you will be able to read in files of any format.
There are two steps to reading from a file. First, read in the file line by line. Second, split up each line into tokens or the different pieces to be dealt with separately.
In this assignment, we can create a file that stores free memory blocks. Each line has two fields, address and size.
1,200 2,50 3,80 4,100 5,150When you test your code, just read in these memory blocks and see if your bst sorts the memory blocks correctly with the corresponding compare functions.
Here is code that reads in a file line by line, print out each line with its line number.
#include <stdio.h > #include <stdlib.h> #define BUFSIZ 120 void display_file(char *filename) { FILE *fp; char buf[BUFSIZ] = "Garbage"; int i; // attempt to open the file, then check whether that worked. if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr,"Could not open file %s\n",filename); return (1); } // for each line of the file, read it in and then print it out i = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { printf ("Line %4d: %s", i, buf); i++; } fclose(fp); }
You can read more about reading files with fgets in this fgets tutorial.
The second step is to learn to use strtok to read the file. Strtok divides up a string into different parts, making separate strings. It does NOT allocate new memory - everything it does is within the original string. Therefore, if you want to use the strings later, you'll need to allocate space for them and copy them over.
To learn how to do this, read this tutorial on strtok.