I've just started to work with UDP sockets in C and I have a question relating to memory management. Often examples show something of the following
struct addrinfo *result; //to store results
struct addrinfo hints; //to indicate information we want
:
:
:
if( (s = getaddrinfo(hostname, NULL, &hints, &result)) != 0){
fprintf(stderr, "getaddrinfo: %s\n",gai_strerror(s));
exit(1);
}
:
:
:
//free the addrinfo struct
freeaddrinfo(result);
I've also seen the introduction of an additonal local addrinfo
structure used in a for
loop to cycle through the result
for the sake of extracting a particular entry...something like this
struct addrinfo *entry; //to store a result from linked list
:
:
:
for (entry = result; entry != NULL; entry = entry->ai_next)
{
:
:
:
}
My question is why is result
the only structure that gets passed to freeaddrinfo
and not hints
or entry
? In other words, I've never seen anyone call freeaddrinfo(hints)
.
One other thing, should I be preallocating memory for or initializing structures of the form addrinfo
? If so, how do I do that?
Yes. More specifically, it allocates memory for the linkedlist pointed to by result
pointer. Since the library is allocating memory on your behalf, library implementors have also providing you with an API to free the memory.
entry
in the example above? Why doesn't that get passed to freeaddrinfoNo. entry
is just a variable used to iterate through the list. It is very much similar to
`for (i = 0; i < n; i++)`
loop you will find anywhere else. i
is just an iterator.
You don't have to use entry
variable at all if you don't want to. You can iterate through the linkedlist with just a while loop
while (result != NULL) {
//Do what you have to do here
result = result->ai_next;
}
If you observe closely, you will see that you are moving the result
variable itself to the end of the list. If you iterate this way, there is no way for you to free the memory since you have lost the starting address which was returned to you by getaddrinfo(). To get around this, you can save the starting address in a temp variable and then use the while loop. Just add this line before the while loop.
struct addrinfo *entry = result; //save the starting address
while (...) {
}
You can call free on entry
pointer now, instead of result
. The effect would be the same.
freeaddrinfo(entry);