0
struct hashLink

{
   KeyType key; /*the key is what you use to look up a hashLink*/
   ValueType value; /*the value stored with the hashLink, an int in our case*/
   struct hashLink *next; /*notice how these are like linked list nodes*/
};

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

I'm trying to iterate through a hashMap with hashLinks. Is this the correct approach? The hashLinks are in an array and may have more hashLinks linked to them in a linked list. I just do not understand how to work pointers to pointers. tableSize is the amount of elements in the array. At each array position there may be more hashLinks linked to the first there.

for(int i = 0; i < ht->tableSize; i ++)
{
    hashLink *current;

    if (ht->table[i] != 0)
    {
        current = ht->table[i];

        while(current->next !=0)
        {
            hashLink *next;
            next = current->next;
            free(current->key);
            free(current);
            current = next;
        }

        free(current->key);
        free(current);
    }
    else 
    {
        continue;
    }

        counter++;
    }
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Gina Brown
  • 11
  • 3

2 Answers2

0

Yes, this does work, but you end up with a hashtable that contains dangling pointers. Also, as Joachim noted, it works as long as you assume that the values contained in the structs are sane, i.e., tableSize contains the number of entries in table and the hashLinks have been correctly allocated.

Your iteration through the links is fine and correclty frees all the hashLinks in the table. However, consider the state of ht after the iteration. You do not change the values of ht->table[i] at all, so after you leave the loop, the pointers will still be stored in the table. If you want to reuse the table, you should set the pointers to 0 when you do not need them anymore, i.e., add ht->table[i] = 0 somewhere after current = ht->table[i];.

If this method is part of the "destructor" of the table (i.e., some method like hashmap_delete(...)), then you can simply free the hashmap after you finished your iteration, i.e., add free(ht); after the for-loop.

0

Simplified:

for(int i=0; i < ht->tableSize; i++)
{
    hashLink *current;

    while (ht->table[i] != NULL) {
        current = ht->table[i];
        ht->table[i] = current->next;

        free(current->key);
        free(current);
    }
}

It can be further simplified to only one loop, but that is left as an exercise to the reader ...


Note: as a side effect, this will set all the pointers in ht->table[] to NULL; which is good, since after freeing the linked lists they have become stale anyway.

joop
  • 4,330
  • 1
  • 15
  • 26