hsearch_r overwrites hash table

让人想犯罪 __ 提交于 2020-01-16 01:10:27

问题


I'm trying to see if I can put a new feature into inotifywait that during the watching phase tracks the list of directories that did not receive any event on them, and before it quits, it prints the list. As of now, inotifywait is capable of showing on directories that received an event. What I'm looking for is for a list of directories that did not receive any event.

To achieve this, I'm taking the following approach.

  1. While inotifywait is placing watches, generate an array of all the directories, and a hashtable using hsearch_r with key as directory name, using the function hadd, and value as the index of the array element just created for this directory.See code here
  2. When an even occurs on a given directory, then, I go to the hash table created in step1, hfind out the value corresponding to this directory name(which is the index of the array element), and set the element at that index in the array to NULL. See search for hash key
  3. Before I exit inotifywait, I will print all the elements in the array that are not NULL. This is essentially the list of directories that did not receive any EVENT from inotifywait.

The problem I'm seeing is, hadd succeeds, and the next statement to hfind for the element just inserted works. When the hsearch_r FIND when an even occurs, step 2 above fails. To see how many elements are there in the hashtable, I hardcoded a dir name in hfind on after I did a hadd. This passes only when the hardcoded directory is just inserted. Subsequently, the next search fails, because, the hashtable seem to have been overwritten with the next element.

I'm hoping that somebody sees where I went wrong. I read the question hsearch_r and posting a new one after a brief discussion there.


回答1:


I haven't looked at your code in depth, but hsearch requires that the keys' lifetime is at least as long as the htables's, because it just stores the entry as it is without making a deep copy of the pointers.

You use a temporary pointer to store the current key; you aprintf to and free this pointer frequently. At the time of the second look-up, the handle is no longer valid. (You could run the code in Valgrind to find such memory access errors.)

You could probably get away with duplicating the string:

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

but that's not a proper solution either, because when you destroy the htable the memory for the keys is leaked.

From 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 doesn't own the data. It just provides a fast look-up for already existing data, which you must manage yourself. (It has other limitations: The maximum number of entries must be known beforehand and items can't be deleted.)



来源:https://stackoverflow.com/questions/33527659/hsearch-r-overwrites-hash-table

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!