Search code examples
cmemoryvalgrindfreestrdup

How to free this strdup?


I am using strdup to duplicated the value inside command. I also free it at the end of my loop to make sure I don't have anything leaking but valgrind seems to disagree with me and says that what is allocated with this strdup is leaking. Any ideas?

Here is my code:

int main(void)
{
init_ui();
hist_init(100);

char *command;
while (true) {
    signal(SIGINT, SIG_IGN);
    command = read_command();
    if (command == NULL) {
        break;
    }
    char *copy = strdup(command);
    char *args[4096];
    int tokens = 0;
    char *next_tok = command;
    char *curr_tok;
    while((curr_tok = next_token(&next_tok, " \t\n\r")) != NULL) {
        if(strncmp(curr_tok, "#", 1) == 0){
            break;
        }
        args[tokens++] = curr_tok;
    }
    args[tokens] = NULL;

    if(args[0] == NULL) {
        continue;
    }
     
    hist_add(copy);
    int builtin_status = handle_builtins(tokens, args);
    if(builtin_status == 0) {
        continue;
    }

    pid_t child = fork();
    if(child == -1){
        perror("fork");
    }
    else if(child == 0){
        int ret = execvp(args[0], args);
        if(ret == -1) {
            perror("execvp");
        }
        close(fileno(stdin));
        close(fileno(stdout));
        close(fileno(stderr));
        exit(EXIT_FAILURE);
    }
    else {
        int status;
        waitpid(child, &status, 0);
        set_last_status(status);
    }
hist_destroy();
free(copy);
}
return 0;
}

Here is what valgrind gives me, I really am trying to understand what is wrong because it seems like what is defined with this strdup is freed:

HEAP SUMMARY:
==359074== in use at exit: 18 bytes in 2 blocks
==359074== total heap usage: 72 allocs, 70 frees, 20,000 bytes allocated
==359074==
==359074== 18 bytes in 2 blocks are definitely lost in loss record 1 of 1
==359074== at 0x483977F: malloc (vg_replace_malloc.c:307)
==359074== by 0x4A7D23E: strdup (in /usr/lib/libc-2.31.so)
==359074== by 0x10A703: main (shell.c:85)
==359074==
==359074== LEAK SUMMARY:
==359074== definitely lost: 18 bytes in 2 blocks
==359074== indirectly lost: 0 bytes in 0 blocks
==359074== possibly lost: 0 bytes in 0 blocks
==359074== still reachable: 0 bytes in 0 blocks
==359074== suppressed: 0 bytes in 0 blocks

Solution

  • strdup() uses malloc() to allocate memory, so in order to reuse strdup(), copy must be freed.

    As UnholySheep commented above, continues causing to ignore the free() statement. One solution to fix this issue is to put an extra free() statement before each continue.