views:

118

answers:

3

Consider this pointless program:

/* main.c */

#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {
    int i;
    for (i = 0; i < 1024; i++) {
        int pid = fork();
        int status;
        if (pid) {
            wait(&status);
        }
        else {
            char *ptr = (char *)malloc(1024*sizeof(char));
            char *args[2] = {"Hello, world!", NULL};
            execve("/bin/echo", args, NULL);
        }
    }
}

Would not freeing ptr constitute a memory leak for either main.c or the other program, or is it going to be freed anyway when execve is called?

A: 

The allocated memory should be freed by exec. After the call completes can't access it anyway.

che
+8  A: 

No.

This is not a memory leak. exec*() will make a local copy of the string data in the args array, then blow away the child process memory image and overlay it with the memory image used by /bin/echo. Essentially all that remains after the exec() is the pid.

Edit:

User318904 brought up the case of exec() returning -1 (i.e., failure). In this case, the child process that has forked but failed to exec does, indeed technically have a memory leak, but as the usual response to a failed exec is to just exit the child process anyways, the memory will be reclaimed by the OS. Still, freeing it is probably a good habit to get into, if for no other reason than that it will keep you from wondering about it later on.

Drew Hall
Thanks. It's not an issue of my being too lazy to add free(ptr). In the actual, slightly-more-complicated case that I have in my real program, I'm actually passing a malloc'ed string to execve, so I'm unable to free it (though I do call free if execve fails).
Nick
@Nick: The source of the memory (stack, heap, static) is irrelevant to the OS--it's all just memory, and it will be replaced and reclaimed automatically and painlessly by the OS.
Drew Hall
+3  A: 

When execve returns -1, yes. Otherwise, maybe.