hsearch_r覆盖哈希表

时间:2015-11-04 16:58:50

标签: c hashtable gnu

我正在尝试查看是否可以将新功能添加到inotifywait中,在观看阶段跟踪未接收任何事件的目录列表,在退出之前,它会打印列表。 截至目前,inotifywait能够显示接收事件的目录。我正在寻找的是一个没有收到任何事件的目录列表。

为实现这一目标,我采取了以下方法。

  1. 虽然inotifywait正在放置监视,使用hsearch_r生成所有目录的数组,并使用key作为目录名,使用函数hadd生成散列表,并将value作为刚为此创建的数组元素的索引目录。See code here
  2. 当在给定目录上发生偶数时,我转到步骤1中创建的哈希表,hfind输出与此目录名对应的值(这是数组元素的索引),并设置数组中该索引处的元素为NULL。请参阅search for hash key
  3. 在退出inotifywait之前,我将打印数组中非NULL的所有元素。这基本上是没有从inotifywait接收任何EVENT的目录列表。
  4. 我看到的问题是,hadd成功,并且刚刚插入的元素的hfind的下一个语句有效。当偶数发生时hsearch_r FIND,上面的步骤2失败。为了查看散列表中有多少元素,我在hfind之后在hadd中硬编码了一个dir名称。仅在刚刚插入硬编码目录时才会通过。随后,下一次搜索失败,因为哈希表似乎已被下一个元素覆盖。

    我希望有人看到我出错的地方。 我在那里阅读了问题hsearch_r并发布了一个新的问题。

1 个答案:

答案 0 :(得分:1)

我没有深入查看您的代码,但hsearch要求密钥'生命周期至少与htables一样长,因为它只是按原样存储条目,而不会生成指针的深层副本。

您使用临时指针存储当前密钥;你经常aprintffree这个指针。在第二次查找时,句柄不再有效。 (您可以在Valgrind中运行代码以查找此类内存访问错误。)

你可能会因为重复字符串而逃脱:

hadd(&tab, strdup(next_file), dir_count);

但这也不是一个合适的解决方案,因为当您销毁htable时,密钥的内存会泄露。

来自man hsearch

  

hdestroy() hdestroy_r()函数不会释放哈希表条目的键和数据元素指向的缓冲区。

htable不拥有数据。它只是为现有数据提供快速查找,您必须自己管理。 (还有其他限制:必须事先知道最大条目数,并且不能删除项目。)