hsearch_r 覆盖散列 table
hsearch_r overwrites hash table
我正在尝试看看是否可以在 inotifywait 中添加一个新功能,即在监视阶段跟踪未收到任何事件的目录列表,并在退出之前打印名单。
截至目前,inotifywait 能够显示接收到事件的目录。我正在寻找的是未收到任何事件的目录列表。
为了实现这一目标,我采用了以下方法。
- 当 inotifywait 放置手表时,生成所有目录的数组,以及使用 hsearch_r 的散列 table,键作为目录名称,使用函数
hadd
,以及值作为刚刚为此目录创建的数组元素的索引。See code here
- 当一个给定的目录出现偶数时,然后,我去step1中创建的散列table,
hfind
取出这个目录名对应的值(这是目录的索引)数组元素),并将数组中该索引处的元素设置为 NULL。参见 search for hash key
- 在退出 inotifywait 之前,我将打印数组中所有非 NULL 的元素。这实际上是未从 inotifywait 接收到任何 EVENT 的目录列表。
我看到的问题是,hadd
成功了,hfind
的下一条语句对刚刚插入的元素有效。当hsearch_r FIND偶数发生时,上面的第2步失败。为了查看散列 table 中有多少元素,我在执行 hadd
之后在 hfind
中硬编码了一个目录名称。这仅在刚插入硬编码目录时通过。随后,下一次搜索失败,因为,hashtable 似乎已被下一个元素覆盖。
我希望有人能看到我哪里出错了。
我阅读了问题 hsearch_r 并在那里进行了简短讨论后发布了一个新问题。
我没有深入查看您的代码,但 hsearch
要求密钥的生命周期至少与 htables
的生命周期一样长,因为它只是将条目存储为它没有对指针进行深度复制。
您使用临时指针来存储当前密钥;你 aprintf
和 free
这个指针经常。在第二次查找时,句柄不再有效。 (您可以 运行 Valgrind 中的代码来查找此类内存访问错误。)
您可能可以复制字符串:
hadd(&tab, strdup(next_file), dir_count);
但这也不是一个合适的解决方案,因为当您销毁 htable
时,密钥的内存就会泄漏。
来自man hsearch
:
The hdestroy() and hdestroy_r() functions do not free the buffers pointed to by the key and data elements of the hash table entries.
A htable
不拥有数据。它只是提供对现有数据的快速查找,您必须自己管理这些数据。 (它还有其他限制:必须事先知道最大条目数,并且不能删除条目。)
我正在尝试看看是否可以在 inotifywait 中添加一个新功能,即在监视阶段跟踪未收到任何事件的目录列表,并在退出之前打印名单。 截至目前,inotifywait 能够显示接收到事件的目录。我正在寻找的是未收到任何事件的目录列表。
为了实现这一目标,我采用了以下方法。
- 当 inotifywait 放置手表时,生成所有目录的数组,以及使用 hsearch_r 的散列 table,键作为目录名称,使用函数
hadd
,以及值作为刚刚为此目录创建的数组元素的索引。See code here - 当一个给定的目录出现偶数时,然后,我去step1中创建的散列table,
hfind
取出这个目录名对应的值(这是目录的索引)数组元素),并将数组中该索引处的元素设置为 NULL。参见 search for hash key - 在退出 inotifywait 之前,我将打印数组中所有非 NULL 的元素。这实际上是未从 inotifywait 接收到任何 EVENT 的目录列表。
我看到的问题是,hadd
成功了,hfind
的下一条语句对刚刚插入的元素有效。当hsearch_r FIND偶数发生时,上面的第2步失败。为了查看散列 table 中有多少元素,我在执行 hadd
之后在 hfind
中硬编码了一个目录名称。这仅在刚插入硬编码目录时通过。随后,下一次搜索失败,因为,hashtable 似乎已被下一个元素覆盖。
我希望有人能看到我哪里出错了。 我阅读了问题 hsearch_r 并在那里进行了简短讨论后发布了一个新问题。
我没有深入查看您的代码,但 hsearch
要求密钥的生命周期至少与 htables
的生命周期一样长,因为它只是将条目存储为它没有对指针进行深度复制。
您使用临时指针来存储当前密钥;你 aprintf
和 free
这个指针经常。在第二次查找时,句柄不再有效。 (您可以 运行 Valgrind 中的代码来查找此类内存访问错误。)
您可能可以复制字符串:
hadd(&tab, strdup(next_file), dir_count);
但这也不是一个合适的解决方案,因为当您销毁 htable
时,密钥的内存就会泄漏。
来自man hsearch
:
The hdestroy() and hdestroy_r() functions do not free the buffers pointed to by the key and data elements of the hash table entries.
A htable
不拥有数据。它只是提供对现有数据的快速查找,您必须自己管理这些数据。 (它还有其他限制:必须事先知道最大条目数,并且不能删除条目。)