Reputation: 1643
I'm using the getaddrinfo()
function that requires a struct addrinfo **
to populate with a linked list of results, but I'm getting a segfault when I try the following code...
int main() {
struct addrinfo **results;
getaddrinfo("localhost", "http", NULL, results); // segfault here
return 0;
}
I'm passing the struct addrinfo **results
to getaddinfo()
which expects that type, how is a segfault being caused?
If I change my code slightly to this...
int main() {
struct addrinfo *results;
getaddrinfo("localhost", "http", NULL, &results); // works
return 0;
}
my code works fine. Whats the difference?
Upvotes: 1
Views: 291
Reputation: 30936
The results
will eventually point to a linked list of struct addrinfos
, and you can go through this list to get all the addresses that match what you passed in with the third parameter. Function will make a pointer point to a linked list and that's why the address of a pointer is expected. When you pass a struct addrinfo*
variable's address, it can be made point to the list. Dereference the passed vaiable will be alright, because the dereferenced value is that of the variable results
. (This explains why struct addrinfo *results;
and &results
works).
It makes point to the linked list. In the source of getaddrinfo
from here
2201 int
2202 getaddrinfo (const char *name, const char *service,
2203 const struct addrinfo *hints, struct addrinfo **pai)
2204 {
...
...
2535 if (p)
2536 {
2537 *pai = p; // in your case this (pai) was uninitialized
2538 return 0;
2539 }
2540
2541 return last_i ? -last_i : EAI_NONAME;
2542 }
In your case you provided an uninitialized value. Dereferencing it is undefined behavior. In your case it resulted in segmentation fault.
To clarify further this would also work
int main(void) {
struct addrinfo *results;
struct addrinfo **results_addr = &results;
getaddrinfo("localhost", "http", NULL, results_addr); // works
return 0;
}
But well the example above is just for the illustration purpose that it is not the double pointer passed was the issue rather initializayion was. Just pass &result
which is much more clear and readable.
Upvotes: 1
Reputation: 37587
getaddrinfo
function will assign a value to pointer to which the passed argument points to. In the first case you are directly passing the value of uninitialized local variable results
so it does not really point anywhere and dereferencing it leads to undefined behavior (which manifests itself into crash). In the second case you are passing a pointer to results
local variable, which will point at the first addrinfo structure if function succeeds.
Upvotes: 0