Question regarding the example of getaddrinfo() in the manual page.

Hello,

I have one question regarding the example of getaddrinfo() (getaddrinfo(3)).

The example is something like:

Code:
s = -1;
for (res = res0; res; res = res->ai_next) {
    s = socket(res->ai_family, res->ai_socktype,
               res->ai_protocol);
    if (s < 0) {
        cause = "socket";
        continue;
    }

    if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
        cause = "connect";
	close(s);
	s = -1;
	continue;
    }

    break;  /* okay we got one */
}
if (s < 0) {
    err(1, "%s", cause);
    /*NOTREACHED*/
}
freeaddrinfo(res0);

My question is: if socket() always fails (e.g., errno == EMFILE) or connect() always fails, the application would call:

Code:
err(1, "%s", cause);

without calling:

Code:
freeaddrinfo(res0);

Though it is not that bad because the memory will be freed anyway when the program exits, wouldn't it be better to call freeaddrinfo(res0); before calling err()?

Thank you.
 
Freeing malloced memory before exiting is actually an overhead, but then again it makes the code's structure more readable and neat. What you should be worrying about is closing file descriptors before exiting (files, sockets, pipes, devices, etc) those sometimes might not get freed by kernel right away (specially sockets).
 
Thank you for your reply.

I like freeing all the memory and closing the file descriptors before exiting.
If valgrind is happy, I am happy :)
 
programmierer75 said:
Thank you for your reply.

I like freeing all the memory and closing the file descriptors before exiting.
If valgrind is happy, I am happy :)

Freeing memory is a good habit, but as a rule of thumb you should also write as less code as possible. Trying to free the memory could lead to some other problems (what if you pass a wrong pointer in your free-ing cycle?), so if the program is going to exit I would assume that trying to free memory is a mistake. Of course, this is also related to what the final program is going to do, that is how it is going to be refactored.
 
I know that it is not always trivial to free all the memory and if I see that the application crashes when it returns from main, I run gdb to find out why and try to fix the bug.

It is always a bit of overhead to do all the cleanup but, I prefer to do it. As you said, because it is a good habit.

This way I don't have to think whether some objects of class A are going to be created and deleted during the lifetime of the program and thus their resources should be freed, and other objects of class B which are going to be global and then its resources are not needed to be freed because they are created only once.

But, it is always a matter of taste :)
 
Back
Top