Определить последний элемент вектора с нулевым символом - PullRequest
1 голос
/ 22 сентября 2019

В документации по использованию сокетов есть описание структуры hostent: https://www.gnu.org/software/libc/manual/html_node/Host-Names.html#Host-Names

Для поля h_addr_list говорится, что это вектор, оканчивающийся нулевым указателем. * 1006Итак, я пытаюсь сделать следующее:

struct in_addr *addr = (struct in_addr *)hostent->h_addr_list[0];
while (addr != NULL) {
  // ...
  addr++;
}

Я ожидал, что переменная addr будет NULL, когда она достигнет последнего элемента в векторе, потому что этот элемент должен быть указателем NULL.
Но на практике этого не происходит.addr никогда не становится NULL.

// hostent->h_addr_list contains 4 meaningful elements
struct in_addr *addr = (struct in_addr *)hostent->h_addr_list[0];
addr++;
addr++;
addr++;
addr == (struct in_addr *)hostent->h_addr_list[3]; // true
addr++;
// here I expected addr to be NULL to terminate the vector, but...
NULL == addr; // false!!!
addr == (struct in_addr *)hostent->h_addr_list[4]; // false

// just to check that it actually NULL terminated
NULL == hostent->h_addr_list[4]; // true
addr = (struct in_addr *)hostent->h_addr_list[4];
NULL == addr; // true

Итак, почему это так?
Что я делаю не так?
Спасибо.

Ответы [ 2 ]

3 голосов
/ 22 сентября 2019

Просмотр документации:

char ** h_addr_list

Это вектор адресов для хоста.(Напомним, что хост может быть подключен к нескольким сетям и иметь разные адреса в каждой.) Вектор завершается нулевым указателем.

h_addr_list - указатель на указатель на символпоэтому последний указатель будет иметь значение NULL, а не указатель на сам указатель.В противном случае он должен быть расположен в очень специфической памяти, чтобы он был нулевым после определенного числа приращений!Просто сделайте:

char **addr_list = hostent->h_addr_list;
while (*addr_list != NULL) {
    // Now *addr points to a valid address
    struct in_addr *addr = (struct in_addr *)*addr_list;

    addr_list++;
}
1 голос
/ 22 сентября 2019

Это вектор указателей.Это последний элемент вектора (указатель), который имеет значение NULL, а не адрес этого элемента.Поэтому попробуйте while (*addr != NULL).

Также то, что вам нужно преобразование (struct in_addr *) для начального значения указателя (чтобы заставить замолчать предупреждение?), Является убедительным признаком того, что эта часть вашего кода неверна.

...