2

I am doing an assignment for school which introduced hashmaps, and so I am creating a templated class for a hashmap that uses the std::hash function. The problem that I am having comes in my insert function, which is shown below:

template <class K, class V>
void HashMap<K, V>::insert(K key, V value)
{
    std::hash<std::string> stringHash;
    int intKey = stringHash(key);
    int bucket = intKey % this->size();
    map[bucket].push_back(std::pair<K, V>(key, value));
}

My error occurs at the line: int bucket = intKey % this->size();.

I don't quite understand why this would give a floating point error since I am doing my work entirely in integers. With the key "banana" and the value 3, the hashed int is 2068534322. In the case where this->size is 5, the modulo should be evaluated as 2.

So, why exactly am I getting a floating point error?

EDIT 1: I also tried this->size() replaced with a hard-coded 5 (which is what this->size should evaluate to), so the this->size isn't having a problem evaluating with a 0.

shermanzach
  • 591
  • 1
  • 6
  • 14
  • If any more information is required to help, please feel free to leave me a comment. I didn't want to give so much information that it would be overwhelming. – shermanzach Jun 02 '14 at 20:07
  • What type is `K`? Are you *sure* `size` is not zero? – David Schwartz Jun 02 '14 at 20:09
  • What's a "floating point error"? Please describe in detail the error you encounter. –  Jun 02 '14 at 20:09
  • 2
    You might assert that `this->size();` isn't `0` when performing this operation! – πάντα ῥεῖ Jun 02 '14 at 20:09
  • I will throw in the assert for later testing, but I have updated the original post with an explanation about the % 0. – shermanzach Jun 02 '14 at 20:13
  • 3
    This is trivially easy for you to debug. Don't be helpless. If the line `int bucket = intKey % this->size();` results in a runtime error, use your debugging tools to determine the values that you pass to the `%` operator. It really could not be easier. Once you know those values, produce a simple SSCCE to illustrate the problem. – David Heffernan Jun 02 '14 at 20:16
  • Any chance this http://stackoverflow.com/questions/12570374/floating-point-exception-sigfpe-on-int-main-return0 is relevant? I have seen weird floating errors when libraries do not agree. – Sean Perry Jun 02 '14 at 20:20
  • std::hash will give you a `size_t` not an `int`. You probably do not want to calculate -1245433%5 and then use the result as the index in `map[bucket]` – nos Jun 02 '14 at 20:31

1 Answers1

4

You do a modulo (== division) operation, so you need to assure your denominator isn't zero

template <class K, class V>
void HashMap<K, V>::insert(K key, V value)
{
    std::hash<std::string> stringHash;
    int intKey = stringHash(key);
    int bucket = this->size() ? intKey % this->size() : intKey; 
       // or whatever makes sense to assign for the latter condition
    map[bucket].push_back(std::pair<K, V>(key, value));
}

Or at least place an assert statement when doing this to track where wrong calls came from:

std::assert(this->size());
int bucket = intKey % this->size(); 
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • If `size()` is the size of the underlying array and equals 0, that means there is no `map` to put stuff into. IOW it's not as easy as substituting a different value for `bucket`. –  Jun 02 '14 at 20:35