Распределяется ли структура 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 Переменная не трогается.

Другие вопросы по тегам