简体   繁体   English

c指向指针的指针如何遍历它

[英]c pointer to pointer how to iterate through it

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. 我正在尝试使用hashLinks遍历hashMap。 Is this the correct approach? 这是正确的方法吗? The hashLinks are in an array and may have more hashLinks linked to them in a linked list. hashLink位于数组中,并且可能在链接列表中具有更多与之链接的hashLink。 I just do not understand how to work pointers to pointers. 我只是不明白如何使用指向指针的指针。 tableSize is the amount of elements in the array. tableSize是数组中元素的数量。 At each array position there may be more hashLinks linked to the first there. 在每个数组位置,可能有更多的hashLink链接到那里的第一个。

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++;
    }
}

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, ie, tableSize contains the number of entries in table and the hashLink s have been correctly allocated. 而且,正如Joachim所指出的,只要您假定结构中包含的值是合理的,它就可以工作,即tableSize包含table的条目数,并且hashLink已正确分配。

Your iteration through the links is fine and correclty free s all the hashLink s in the table. 通过链接进行的迭代是很好的,并且free的所有hashLink However, consider the state of ht after the iteration. 但是,请考虑迭代后ht的状态。 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. 您根本不需要更改ht->table[i]的值,因此,退出循环后,指针仍将存储在表中。 If you want to reuse the table, you should set the pointers to 0 when you do not need them anymore, ie, add ht->table[i] = 0 somewhere after current = ht->table[i]; 如果要重用该表,则在不再需要它们时,应将其指针设置为0,即在current = ht->table[i];之后的某个地方添加ht->table[i] = 0 current = ht->table[i]; .

If this method is part of the "destructor" of the table (ie, some method like hashmap_delete(...) ), then you can simply free the hashmap after you finished your iteration, ie, add free(ht); 如果此方法是表的“析构函数”的一部分(例如,诸如hashmap_delete(...) ),则可以在完成迭代后简单地free哈希图,即,添加free(ht); after the for -loop. for循环之后。

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; 注意:作为副作用,这会将ht-> table []中的所有指针设置为NULL; which is good, since after freeing the linked lists they have become stale anyway. 这很好,因为在释放链接列表之后,它们无论如何都变得过时了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM