I have programming experience with higher-level languages, and have started coding in plain C a couple of weeks ago (for academic reasons). I want to implement a data structure something like a map<char,myStruct*>.
If that isn’t clear enough: I want a “mapping” for every possible SINGLE char onto a pointer to a structure I define somewhere else. If there was a way to ensure that no 2 chars can point to the same struct (without checking every other char when inserting a new element onto the map) that would be neat, but that is not strictly necessary. I also need to be able to remove pairings from the map, and to reinsert the pairings with the same Key but different pointers.
I have thought this through, and figured I could create a pointer array the length of all possible chars, and just store the corresponding pointer using the char as the array index (since it is just a number constant). This might very well work but it seems kind of inefficient to allocate that much space for addresses if I end up using only a couple of chars in my application.
Still, I wasn’t able to think of any alternative solutions (considering I’m a C newbie, not that surprising). I would be grateful for any, if even vague, suggestions in the right direction.
Just as you say (and as a commenter suggested), the easiest thing is to just do an array with a static size equal to the max value of the character data type:
Assuming 64-bit pointers and 8-bit
chars, this would occupy 8 * 256 = 2,048 bytes of memory for the entire map (excluding of course the “user data” which is what you store). For a program running on a 64-bit system, 2 KB of memory is trivial, and the ease of implementation and speed you get from this should balance the wasted memory quite nicely, in my opinion.The simplest thing to do if you still want to limit the “physical” size of the array would be to hash the single character, but then you need to start dealing with hash collision which immediately makes it more complicated.
You could do something like:
Here we’ve halved the size of the pointer array, but the cost of each value has increased. Also you’re going to need dynamic allocations when inserting collided values.
You could further compact it by doing e.g.
Here each value in the array is a full
ValueChain“list header”, rather than just a pointer to one. On a 64-bit machine this would probably use about 558 bytes for themappingarray, but you wouldn’t need to do any dynamic allocations until you detect a collision.The hashing for these could be just
const char key = myChar % MAP_SIZE;to a first approximation, I guess.