Instead of pointers use offsets (relative for example to the beginning of the shared memory) because the shared memory might be mapped to different offsets in different processes. A hash table implementation with separate chaining consists of a hash array, and an items array (usually without holes in the items array). The hash table entry contains a hash for the item and an index to the first item in the table with the specified hash, in the items table you also link the items that have the same hash by indices. So the hash table isn't a problem if implemented correctly, you should be careful with the data you place in it, the data should be "self contained" so that it doesn't store data outside the hash table otherwise your data must use an allocator that restricts allocations a pool that resides in your shared memory. This allocator thingy becomes hard-to-manage easily so go with self contained items without pointers and allocation instead!
If you write your hash table implementation (lets say a template) then you have to construct it with placement new and destruct it with direct destructor call on the specified shared memory area.
http://www.parashift.com/c++-faq-lite/placement-new.html[
^]
You can find C++ hash table implementations with google, all you have to modify is changing the pointers to indices.