0

I'm just learning about pointers in C. I'm working with the following structs for a hash map:

struct hashLink {
   KeyType key; /*the key is used to look up a hashLink*/
   ValueType value; /*an int*/
   struct hashLink * next; /*these are like linked list nodes*/
};

struct hashMap {
    hashLink ** table; /*array of pointers to hashLinks*/
    int tableSize; /*number of buckets in table*/
    int count; /*number of hashLinks in table*/
};

Using a command line, I give the program the name of a file that has a test sentence in it, such as "All's fair in love and in war." Using a loop, I use a method called getWord which returns char* word. Still in the loop, it then calls and passes a hashMap, word, and the value 1 to insertMap().

The insertMap function is as follows:

void insertMap (struct hashMap * ht, KeyType k, ValueType v)
{
    int idx;
    idx = stringHash(k) % ht->tableSize; //hash k to find the index

    if (idx < 0) idx += ht->tableSize;

    if (containsKey(ht, k)) {  //check to see if k is already in the hash map
            ht->table[idx]->value++;  // if yes, increment value to reflect number of times a word appears in the sentence.
        }
    else {  // if k is not in the hashmap, create a new hashLink
        struct hashLink *newLink = (struct hashLink *)malloc(sizeof(struct hashLink));
        newLink->value = v;
        newLink->key = k;
        newLink->next = ht->table[idx];
        ht->table[idx] = newLink;
        ht->count++;
    }
}

Here's the problem. This is a hashmap with chaining. When a word is passed in the second time, the program doesn't recognize it as the same word and creates a new link in the hash map. For example, in the above sentence example, using debugger, I can see that the key for the first instance of "in" is 0x8f4d00 'in'. The next instance it might be 0x8f4db8 'in'. Clearly, I am not using char* word correctly, because once it's passed into insertMap as KeyType key, a new hashLink is created for the second "in".

I've tried a number of things, but I started getting segmentation faults and thought I'd better quit before I did some real damage :). Any suggestions for how I should use be using char* word before I pass it to insertMap(), so that only the word itself, rather than the pointer to it, is passed and stored would be greatly appreciated. Or should I go ahead and pass the pointer, but handle it differently than I currently am? Thanks.

user1852050
  • 555
  • 2
  • 12
  • 17
  • Where is `containsKey`? – n. 'pronouns' m. Mar 10 '13 at 03:55
  • by passing char * you are just passing the address of the first char. you should pass char[] and not char*. same criteria as you would do in sizeof remember? – Koushik Shetty Mar 10 '13 at 03:56
  • I still didn't read the whole question, but I have a small comment on your code: it seems in the struct definition, you have a `hashlink` variable `tables` which you say is an array of pointers; keep in mind that arrays and pointers are not the same thing, and they can be used interchangeably only up to the case of 1D or 2D arrays, because of the way they decay. See [here](http://stackoverflow.com/questions/3920729/in-c-c-is-char-arrayname-a-pointer-to-a-pointer-to-a-pointer-or-a-pointe?rq=1) – naxchange Mar 10 '13 at 05:46
  • Read, study carefully _and understand_ this [tutorial](http://pw1.netcom.com/~tjensen/ptr/pointers.htm). – vonbrand Mar 10 '13 at 15:28

1 Answers1

1

You need to compare the values that are pointed to by the char *word pointer, but you'll still usually want to pass the pointer itself to your function. Once there, you de-reference the pointer to examine what it points to in memory.

For example, if you wanted to compare a key from the hashmap to a char *k:

strncmp(ht->table[i]->key, k, length);

You can do this yourself quite simply:

int compare_strings(char *s1, char *s2, int len)
{
  int i;
  for (i = 0; i < len; i++)
    if (*s1 != *s2)
      return 0;

  return 1;
}

The above function will compare len characters from s1 and s2. This is just an example, normally you'd want to do bounds checking and test the pointers passed in.

Mr. Shickadance
  • 5,003
  • 9
  • 38
  • 54