Search code examples
cvectornull-pointer

Detect the last element of a null terminated vector


In the documentation for using sockets there is a description of the hostent structure: https://www.gnu.org/software/libc/manual/html_node/Host-Names.html#Host-Names

For the h_addr_list field it says that it is a vector terminated with a null pointer.
So, what I try to do is:

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

I expected that addr variable is NULL when it reaches the last element in the vector, because that element should be a NULL pointer.
But on practice that does not happen. addr never becomes 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

So, why is it like this?
What am I doing wrong?
Thanks.


Solution

  • Looking at the documentation:

    char **h_addr_list

    This is the vector of addresses for the host. (Recall that the host might be connected to multiple networks and have different addresses on each one.) The vector is terminated by a null pointer.

    h_addr_list is a pointer to a pointer to a char, so the last pointer will be NULL, not the pointer to the pointer itself. Otherwise it would have to be located at very specific memory for it to be zero after a certain number of increments! Just do:

    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++;
    }