My Project
|
struct
) and how to embed one
structure within another.&
malloc()/calloc()/free()
In this assignment, you will use a hash table with chaining. You will learn
more about hash tables in your Data Structures course. The data structures you
use are already defined for you in symbol.h/symbol.c
.
The hash function you will use computes an integer value from a string. More
than one string may hash to the same value. However, a good hash
function will minimize this. You can think of the hash value as an "alias" for
the string. Thus, when searching for a string, you first search for the hash
value (using integer comparison, which is fast) and only when you find an equal
hash value, use strcasecmp()
(much slower than integer comparison)
to verify you have found the string of interest.
The symbol table contains a hash_table
which is an array. The
index into this array is calculated as index = hash-value % size-of-hash-table
.
A given index in the hash table contains a pointer to the head of a singly
linked list of nodes containing symbols whose hash values share the same index.
There is a scond optional table in the symbol table structure. It is a
dynmacilly allocated array of char*
(C's version of strings),
that allow a fast lookup of a symbols name given its address.
Here is a graphical representation of the data structure. Make sure you understand how the declarations relate to the drawing.
cd
to itSave Target As..
for each
of the files.
symbol.h
(do no modify)symbol.c
(complete this file)testSymbol.c
(do not modify)Makefile
(do not modify)make
./testSymbol
. You will see a usage message which tells
you how to use the program. You may also use help
within the
program to reprint the messagesymbol_init()
malloc()/calloc()
. You must also allocate
and initialize addr_table[]
.
symbol_search()
symbol_add()
and symbol_find_by_name()
. The basic
algorithm to search for a symbol by name is:
symbol_hash()
hash-value % table-size
)NULL
otherwisesearch
in the
test driver.
symbol_add()
add
command the the test driver.
A hash table is designed to spread out the entries, often sacrificing space for speed. To thoroughtly test your function, you will need to force multiple names to occupy the same index in the hash table. Think about the pigeon hole principle from CS161, study the code and you should understand what to modify to test your code. Your code will be tested with a different values.
symbol_find_by_name()
is only a few lines of code,
since most of the work is done by symbol_search()
. Test by using the
command get
in the test driver.symbol_find_by_addr()
is only a few lines of code,
since it's basically just an array lookup. Test by using the command label
in the test driver.symbol_iterate()
is around ten lines of code.
It consists of nested loops with the outer loop varying over the symbol table
and the inner loop varying over the linked list at the current index. Using
a function pointer is really straight forward. The actual line of code you will
use is: (*fnc)(symbol, data);
This is almost identical to calling a normal function namedfnc()
except that you would write:fnc(symbol, data);
You can test your function using the commandscount/list
in the test driver
symbol_reset()
consist of two nested loops as you
wrote for symbol_iterate()
. For each node you will need to free
any allocated memory. Test it with the command reset
in the test
driver.symbol_term()
may use symbol_reset to
do most of the work. Be sure and deallocate the main symbol table as well. This
will be tested when the test driver terminates.
Thoroughly test your code using the test driver. You may find it convenient to build a file containing a series of commands to execute, then use this file to test your program without having to type in commands over and over. Execute
./testSymbol <0/1> < testFile
Preliminary testing:
symbol.c
using the
checkin
program or the Checkin tab of the course web page.
Use the key SYMBOL. At the terminal type:
~cs270/bin/checkin P4 symbol.c