CMSC313, Computer Organization & Assembly Language Programming, Fall 2012
Project 8: Generic Linked List in C
Due: Thursday November 15, 2012, 11:59pm
Objective
The objective of this programming project is to practice
working with void * pointers and function pointers.
Assignment
Your assignment is to add two features to the generic linked list
program discussed in class, namely searching and type selection.
Recall that the linked lists discussed in class (see Lecture 19) were polymorphic in
the sense that the same linked list can have nodes which hold different
data types. The linked list functions are genuinely polymorphic since
there is just one set of functions that works with linked list of int,
linked list of double, linked list of strings ... Adding a new
type to the linked list does not require access to the source code
for the linked list functions.
Each node in the linked list has a pointer to a virtual function
table (borrowing from C++ parlance). This table holds pointers to
functions that operate on the linked list node. There is only one table
per type (not one table for each node). In the programs shown in
class, the table held only two functions: one for printing the data in
the node and one for deallocating the node. For this assignment, you
will add two more functions to the table: comparison and cloning.
Searching in a polymorphic linked list requires a small trick. Suppose
we want to search the linked list for a node that has the int
value 3. Some nodes in the list might not have int data, they
might even carry non-numerical data (e.g., strings or linked lists). In
fact, the code you write should be compatible with linked list nodes
that will be defined in the future. Fortunately, there is an easy way to
determine if a linked list node compatible for comparison: just check to
see if the node is pointing to the correct virtual function table!
The prototype of the search function is:
base_node *LL_Search(base_node *header, void *p) ;
The intent here is that p is a pointer to a linked list node
and we want search in the linked list pointed by header
for a node that has the same value as the data in *p. Since
p is a pointer to a linked list node, you can use it to get the
address of the virtual function table for its data type. Now, for each
node in the linked list you first check to see if that node points to
the same virtual function table. (This is called run-time type
identification.) If it does, then the two nodes are
compatible and you can call a comparison function to see if the values
are equal.
Where is this comparison function? In the virtual function table, of
course!
The second function that you must implement have this prototype:
base_node *LL_Select_Type(base_node *header, void *p) ;
The function should return a pointer to a new linked list that has
all the nodes with the same type as p. For example,
if the linked list has the values:
2 18.700000 57.200000 14 44 2 31 94.100000 72
Then a request to select the nodes with type int should produce
a linked list with the values 2, 14, 44, 2, 31 and 72.
Again, you can use the pointer to the virtual function table to determine
whether a node has the same type as p. Since you have to return
a new linked list, each node in the list must also be new. Thus, you
need to add a "clone" function to the virtual function table. This
function should make a copy of the node (deep copy) and return a pointer
to the newly created node.
Implementation Notes
- See Lecture 19 notes for
how the polymorphic linked list was developed.
- The files you need are available here:
/afs/umbc.edu/users/c/h/chang/pub/cs313/proj8.tar
Copy the proj8.tar file to your own directory. Then unpack it with the
Unix command:
tar -xvf proj8.tar
This will create a new subdirectory named proj8 in the current directory.
In the directory, you will find the files:
README
ll.c
ll.h
ll_double.c
ll_double.h
ll_int.c
ll_int.h
proj8.c
You need to add code to the functions LL_Search() and
LL_Select_Type() in ll.c. You need to implement
cmp_int_node() and clone_int_node() in ll_int.c
and
cmp_double_node() and clone_double_node() in
ll_double.c.
-
Update:
For consistency with other C comparison functions,
cmp_int_node() and cmp_double_node() should return a
negative number, zero or a positive number if the first parameter
is, respectively, smaller than, equal to or greater than the second
parameter.
The main() function in proj8.c exercises the linked
list functions you implement.
- The virtual function tables have already been filled out for you.
For example, in ll_int.c you have:
one_ftype Int_VFuncs[4] = {
(one_ftype) &print_int_node,
(one_ftype) &del_int_node,
(one_ftype) &cmp_int_node, // new
(one_ftype) &clone_int_node // new
} ;
Note that this places functions with different signatures in the same
array. For example, cmp_int_node() takes 2 parameters whereas
print_int_node takes only 1.
Since we just store the entry address of the functions (which is always
4 bytes), there is enough memory in the array.
However, you must be careful when you retrieve a function pointer from
the virtual function array. You must type cast the function back to
the correct type. Otherwise the C compiler will complain that you are
invoking the comparison function with 2 parameters.
Compatible type definitions for the function pointers have already been
defined for you in the header file ll.h:
typedef void (*one_ftype) (void *) ;
typedef int (*cmp_ftype) (void *, void *) ;
typedef void * (*clone_ftype) (void *) ;
enum vf_index { PRINT_VF = 0, DEL_VF, CMP_VF, CLONE_VF } ;
Thus, if ptr points to a linked list node, you can retrieve the
comparison function with something like:
cmp_ftype cmpf ;
...
cmpf = (cmp_ftype) ptr->vfunc[CMP_VF] ;
- Yes, you are supposed to use the linked list functions that are
already implemented. E.g., LL_New(), LL_Insert() and
LL_Extract() should all be quite useful.
Turning in your program
Use the UNIX submit command on the GL system to turn in
your project.
You should submit 3 files: ll.c, ll_int.c and
ll_double.c. Make sure that your project compiles with the
original header files ll.h, ll_int.h and
ll_double.h.
The UNIX command to submit should look like:
submit cs313 proj8 ll.c ll_int.c ll_double.c
Last Modified:
22 Jul 2024 11:28:31 EDT
by
Richard Chang
to Fall 2012 CMSC 313 Homepage