The goal of this project is for you to practice using pointers and dynamic memory.
In this project you will implement a map.
Recall that a map (also called a dictionary or
associative array)
associates keys with values.
The most familiar example is Java's HashMap
.
See the Map in Java's API
as an example of the functionality.
This map will be implemented using a linked list, so the code we saw at the beginning of class on Friday (Oct 12) will be a handy comparison. Tesist the temptation to refer to your code as a hash map. The "hash" in "hashmap" refers to a specific way to implement a map (or set). We are not doing hashing in this lab. But we will learn about hashing later in the semester.
Your map will associate strings with strings (that is, both the keys and values will be strings), so this will also give you a little practice working with strings in C (although we will be doing no real processing on strings). The driver program makes a map from countries to capitals.
Copy the given code.
mkdir proj4 cd proj4 cp ~tvandrun/Public/cs245/proj4/* .
First look at the driver program (driver.c
)
to get a handle on what your map needs to do.
The first part of the file contains a big static array with the raw data we are going
to use.
You can largely skip over that---direct your attention to
the main()
function.
(If you look at the list of countries, you'll notice some entries like Northern Ireland, Puerto Rico, Transnistria, and Palestine, which for various reasons (status, independence, recognition, etc) raise the question of how we define country. I simply grabbed this list from Wikipedia's list of national capitals, which you can check out yourself if you're interested in the political status of any of the nations included. No political message is intended on my part by including or excluding any entity.)
Notice in the main()
function we have
a map pointer m
which we initialize to the result
of create()
, which allocates an empty map.
We have a loop to populate the map.
Then we exercise the functions containsKey()
and put()
.
Then we iterate through all the associations in the map.
Recall that with Java's HashMap
this is done
by getting the keyset fromt he hash map, an iterator from the keyset,
and using the keys (gotten from the keyset) to obtain the value for
each key, like this:
for (Iteratorit = map.keySet().iterator(); it.hasNext(); ) { String key = it.next(); System.out.println(key + " " + map.get(key)); }
Lacking both a good "set" type and iterators in C,
what we do here is definte a function numKeys()
which allocates and returns an array containing all the keys.
Notice that the result is stored in a variable keySet
that has type char**
, which
is essentially "array of strings."
(Temember that strings are really just character arrays,
and arrays are just pointers.
So char**
is interpreted as
"pointer to (array of) pointer(s) to (array of) char(s)."
Make sure you understand that.
Ask for help if you don't.
Finally we call destroy()
which shall
deallocate everything in the map.
Now you need to master map.h
.
The structs for nodes and the map are already written for you
but you must understand them completely.
Notice that the nodes do not have a single datum
but two data: a key and a value.
Then look at the functions in map.c
.
create()
and numKeys()
are written for you as examples.
I also have provided a functiongetNode()
,
which is not listed in map.h
.
It is for convenience---the analogue of a private helper method
in Java.
In the following specific tasks for you to do,
remember that anything you allocate (or that is allocated in
the code you're given) must have an identifiable deallocation
somewhere in the code.
However, notice that all the strings themselves are allocated statically.
You never need to copy the contents of these strings---just store
and refer to them using pointers.
You do not need to deallocate them--in fact, you must not.
free()
won't like it if you try to deallocate something
that is statically allocated.
put()
Given a pointer to a map, add the association given by the parameters. (What if there already is an association for the given key?) This will likely involve allocating a new node; by the end of the project, you should be able to account for when it is deallocated.
get()
Retrieve the value, given a key.
rem()
Remove a key (and its value) from the map.
Don't forget to clean up and deallocate the node---but don't deallocate
the contents of the node.
Also, remove should return the value associated with
the indicated key (which is now being removed), if any (NULL otherwise).
(See the remove()
method in
Java's HashMap
class.)
containsKey()
Test to see if a given key exists in the map.
keys()
Here's the hard one. You need to allocate an appropriate-lengthed array of strings (that is, an array for holding character pointers). Then you need to populate it. (Where is this deallocated? Look in the driver.)
destroy()
Clean up and deallocate all the nodes and the map itself (but not the strings).
Copy all the files you made or modified to a turn-in directory I've made for you.
cp -r lab2-turnin /cslab.all/ubuntu/cs245/turnin/(your user id)
DUE: Monday, Oct 29, at 5:00 pm.