14.4.6. Удаление вершины дерева и удаление дерева: tdelete()
tdestroy()Наконец, вы можете удалить элементы из дерева и, на системах GLIBC, удалить само дерево целиком:
void *tdelete(const void *key, void **rootp,
int (*compare)(const void*, const void*));
/* Расширение GLIBC, в POSIX нет: */
void tdestroy(void *root, void (*free_node)(void *nodep));
Аргументы для tdelete()
tsearch(): ключ, адрес корня дерева и функция сравнения. Если в дереве найден данный элемент, он удаляется, и tdelete() возвращает указатель на NULL. С этим поведением следует обращаться в своем коде осмотрительно, если вам нужен первоначальный удаляемый элемент, например, для освобождения занимаемой им памяти.struct employee *е, key; /* Объявления переменных */
void *vp, *root;
/* ...заполнить ключ для удаляемого из дерева элемента... */
vp = tfind(&key, root, emp_name_id_compare); /* Найти удаляемый элемент */
if (vp != NULL) {
e = *((struct employee**)vp); /* Преобразовать указатель */
free(e); /* Освободить память */
}
(void)tdelete(&key, &root, emp_name_id_compare); /* Теперь удалить его из дерева */
Хотя это и не указано в справочных страницах или стандарте POSIX, под GNU/Linux, если вы удаляете элемент, хранящийся в корневой вершине, возвращается значение новой корневой вершины. Для переносимого кода не следует полагаться на это поведение
Функция tdestroy()
NULL! Это приведет к аварийной ситуации.14.5. Резюме
• Иногда бывает необходимо выделить память, выровненную по определенной границе. Это осуществляет posix_memalign()
memalign() также выделяет выровненную память, но не все системы поддерживают освобождение памяти с помощью free().• Блокирование файлов с помощью fcntl()
• GNU/Linux функция lockf()
fcntl(); блокировки функции BSD flock() совершенно независимы от блокировок fcntl(). Блокировки BSD flock() используются лишь для всего файла в целом и не работают на удаленных файловых системах. По этим причинам использование блокировки flock() не рекомендуется.• gettimeofday
struct timeval. Эти значения используются utimes() для обновления времени доступа и модификации файла. Системные вызовы gettimer() и settimer() используют пары struct timeval в struct itimerval для создания интервальных таймеров — сигнальных часов, которые «срабатывают» в установленное время и продолжают срабатывать впоследствии с заданным интервалом. Три различных таймера обеспечивают контроль тех состояний, когда таймер продолжает действовать.• Функция nanosleep()
struct timespec, которая указывает время в секундах и наносекундах, чтобы приостановить выполнение процесса в течение определенного интервала времени. У нее есть удачная особенность не взаимодействовать вообще с механизмами сигналов.