Почему опрос требует, чтобы его основной параметр жил за пределами вызова?
Я изучаю функцию poll() для моего небольшого проекта и заметил, что этот фрагмент разбился:
ErrorCode XNotifier_Linux::updatePoll()
{
ErrorCode ret = Success;
struct pollfd descriptors = { m_fd, IN_MODIFY, 0 };
const int nbDescriptors = poll(&descriptors, m_fd+1, 10*1000);
if (descriptors.events & (POLLIN | POLLPRI))
ret = DataIsPresent;
return ret;
}
Valgrind весьма полезен, потому что указывает на то, что поле poll ufds
в унифицированном виде:
==833== Syscall param poll(ufds.fd) points to uninitialised byte(s)
==833== at 0x569CB28: poll (in /lib64/libc-2.14.1.so)
==833== by 0x400F7A: xnot::XNotifier_Linux::updatePoll() (linux.cpp:72)
==833== by 0x400D4B: xnot::XNotifier_Linux::update() (linux.cpp:28)
==833== by 0x400FF4: main (linux.cpp:90)
==833== Address 0x7fefffbb8 is on thread 1's stack
Как descriptors
был создан в стеке, я понимаю, что когда функция возвращает, указатель на descriptors
больше не действителен Я думал, что этот указатель может быть использован после возврата функции. Чтобы подтвердить это, я изменил строку объявления дескрипторов на: static struct pollfd descriptors = { m_fd, IN_MODIFY, 0 };
и авария исчезла.
Почему дескрипторы должны переживать вызов poll()? (Или я что-то не так понял?)
P.-S.: дескриптор был заполнен inotify m_fd = inotify_init();
1 ответ
Вы неправильно определили проблему.
const int nbDescriptors = poll(&descriptors, m_fd+1, 10*1000);
Это неправильно, потому что первый аргумент poll
массив (указатель на), а второй аргумент - количество элементов в этом массиве.
В результате системный вызов выполняет чтение за концом массива. Объявив это static
ты просто переместил вещи в память и повезло.
Тебе нужно:
const int nbDescriptors = poll(&descriptors, 1, 10*1000);