Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Hsearch_r перезаписывает хеш-таблицу

Автор вопроса: venkraoОтветов: 1

Я пытаюсь посмотреть, смогу ли я добавить новую функцию в inotifywait, которая во время фаза наблюдения отслеживает список каталогов, в которых не было никаких событий, и перед завершением распечатывает этот список. На данный момент inotifywait может отображать каталоги, получившие событие. Я ищу список каталогов, которые не получили никаких событий.

Чтобы добиться этого, я использую следующий подход.

  1. Пока inotifywait размещает часы, создайте массив всех каталогов и хеш-таблицу, используя hsearch_r с ключом в качестве имени каталога, используя функцию hadd и значение в качестве индекса элемента массива, только что созданного для этого каталога.см. код здесь
  2. Когда даже происходит в данном каталоге, я перехожу к хэш-таблице, созданной на шаге 1, hfind из значения, соответствующего этому имени каталога (которое является индексом элемента массива), и устанавливаю элемент по этому индексу в массив в NULL. См. поиск хеш-ключа
  3. Прежде чем выйти из inotifywait, я распечатаю все элементы массива, которые не равны NULL. По сути, это список каталогов, которые не получили никакого СОБЫТИЯ от inotifywait.

Проблема, которую я вижу, заключается в том, что hadd выполняется успешно, и следующий оператор hfind для только что вставленного элемента работает. Когда hsearch_r НАЙТИ, когда происходит даже, шаг 2 выше не выполняется. Чтобы увидеть, сколько элементов содержится в хеш-таблице, я жестко закодировал имя каталога в hfind после того, как сделал hadd. Это проходит только тогда, когда жестко закодированный каталог только что вставлен. Впоследствии следующий поиск завершается ошибкой, потому что хэш-таблица, похоже, была перезаписана следующим элементом.

Я надеюсь, что кто-нибудь увидит, где я ошибся. Я прочитал вопрос hsearch_r и опубликовал новый после краткого обсуждения.

  • Вопросы, требующие помощи в отладке (почему этот код не работает?), должны включать желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения, в самом вопросе. Как создать минимальный, полный и проверяемый пример Нет гарантии, что предоставленная вами ссылка будет работать завтра. Это гарантирует, что код будет доступен для обучения будущих пользователей SO. David C. Rankin 04.11.2015

cgnuhashtable

Ответы

Ответ 1 · рейтинг 1 · M Oehm

Я не изучал ваш код подробно, но hsearch требует, чтобы время жизни ключей было не меньше, чем у htables, потому что он просто сохраняет запись как есть, не делая глубокую копию указателей.

Вы используете временный указатель для хранения текущего ключа; вы часто aprintf и free этот указатель. Во время второго поиска дескриптор уже недействителен. (Вы можете запустить код в Valgrind, чтобы найти такие ошибки доступа к памяти.)

Вероятно, вам может сойти с рук дублирование строки:

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

но это тоже не правильное решение, потому что когда вы уничтожаете htable, происходит утечка памяти для ключей.

Из man hsearch:

Функции hdestroy() и hdestroy_r() не освобождают буферы, на которые указывают элементы ключа и данных записей хэш-таблицы.

htable не владеет данными. Он просто обеспечивает быстрый поиск уже существующих данных, которыми вы должны управлять самостоятельно. (У него есть и другие ограничения: максимальное количество записей должно быть известно заранее, и элементы нельзя удалять.)

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы