A. As implementor you can't (with the interface we are using). But the function returns a pointer to the client, who is then able to free the memory if that is necessary/desired.
Q. On the web page you printed an inventory list in response to a command of L, shouldn't that have done a lookup?
A. My fault, yes, the list should come as a response to the commad 'I' as mentioned elsewhere on the page. 'L' is for lookup. (The typo is now fixed, but you don't need to print out the assignemtn again for just that.)
Q. When I print my inventory list, all the values in the table are the same. What happened?
A. You need to make sure that each pointer-to-data which you send to the symbol table is in a differenet location, else each time you change one you are changing them all. Remember that the implementation only knows the address, it is up to client to allocate memory, make sure that different memory is used for each key, etc.
You may wish to write a CopyData function which allocates new memory, copies you data to that new location and returns the pointer to that memory. If you then pas the return value of this function to the implementation without storing it on the client side, you will have a hard time messing up.
Another option is to allocate new memory each time you read a value from the user. The debugging is made easier if you set such a pointer to NULL immediately after storing it in the symbol table.
Q. How do I deal with the void* types in client code?
A. The client must work with some pointer type (probably a pointer to a struct in many cases, but a pointer to an int, etc, would work too.) Once the void* has been cast back to this type, the client can access its data, free the memory, etc.
Also, don't forget to allocate memory on the client side.
Q. When we delete an item do we delete the item or just one quantity of that item?
A.
Delete the whole thing.
In fact, since the implementation side doesn't know the contents of the
value, DeleteKeyFromSymbolTable can't decrement the quantity.