Search code examples
cforkposixdaemon

Should a daemonising parent free() memory after forking its child?


Let's say we've got some code like this:

int main() {
    FILE *f_conf = fopen("conf.conf");
    /* File Open Error Handling */

    char *buf = malloc(128);
    /* Malloc Error Handling */

    fgets(buf, 128, f_conf);
    fclose(f_conf);

    pid_t pid = fork()
    /* Fork Error Handling */

    if (pid) {
        free(buf); /* Should this free be called? */
        return 0;
    }

    while (1) {
        /* Do Stuff */
    }

    return 0;
}

In general, I prefer to free memory prior to returning, since any impact to impact performance is minimal, and it helps with automated tooling to detect memory leaks. That said, the performance / best practices are less clear to me here, as it makes little sense to run these tools on a daemon. This leads me to two questions:

  1. Would freeing memory (such as *buf) of a parent process prior to return affect performance of the child? I'm thinking there could be some (either positive or negative) by the way copy-on-write is implemented.
  2. Is it considered good practice for the parent to free leftover resources?

Solution

  • I consider it good practice to limit the allocation of a thing to exactly the executable region that it is valid for. To me, the free is part of the documentation -- this thing is no longer valid or accessible. In all things programming, conciseness yields clarity; and clear programs can be improved and optimised; incoherent ones cannot.

    In terms of performance across a fork, if you are down to measuring the page-cache effect, you are probably in a very dark place. Fundamentally, the process' pages will point to the same underlying page; if one relinquishes the page, the other gets it free-of-charge [ no point in copying if refcount == 1 ]. Realistically, all that happens is a few linked list nodes get updated, and you can't really measure it.

    That said, if you are carrying around an allocation for an entire DVD or something, yeah, you might consider mapping it shared.