Распределяется ли структура addrinfo **res, когда getaddrinfo() возвращает ненулевое значение?
У меня возникают проблемы с утечкой памяти во встроенном приложении, и, глядя в код, я не вижу freeaddrinfo(), когда getaddrinfo() возвращает ненулевое значение:
s = getaddrinfo(hostname, port, &hints, &result);
if (s != 0) {
log_error();
} else {
// do stuff
freeaddrinfo(result);
}
Может ли это привести к утечке памяти? Я попытался заглянуть в справочную страницу, но в ней не указано явно.
2 ответа
Спецификация не говорит, что result
не назначается, если происходит сбой, поэтому кажется, что соответствующая реализация могла бы сделать это.
Почему бы не освободить это безоговорочно?
result = 0;
s = getaddrinfo(hostname, port, &hints, &result);
if (s) {
// log error
} else {
// success
}
if (result) {
freeaddrinfo(result);
}
В идеале вы могли бы позвонить freeaddrinfo(result)
без проверки result
NULL, но, хотя стандарт подразумевает, что все в порядке, я бы на это не рассчитывал.
Хотя это правда, что стандарт немного расплывчат в этом, единственная интерпретация, которая имеет смысл, - это рассматривать ошибку как альтернативу результату. Вот как работают другие функции libc, и вот как getaddrinfo()
используется в примерах даже в стандарте.
См.: http://pubs.opengroup.org/onlinepubs/9699919799/functions/freeaddrinfo.html
Я не думаю, что есть необходимость изобретать способы обойти это, если вы не имеете дело с известной неработающей реализацией. Функции POSIX не требуют обнуления указателей, используемых для вывода, если не указано иное.
Из приведенной выше ссылки:
После успешного возврата getaddrinfo() местоположение, к которому относятся точки res, должно ссылаться на связанный список структур addrinfo, каждая из которых должна указывать адрес сокета и информацию для использования при создании сокета, с которым будет использоваться этот адрес сокета.
Довольно ясно, что стандарт написан с предположением, что в других случаях res
Переменная не трогается.