Search code examples
cpointersdynamic-memory-allocationfree

free(): double free detected in tcache 2 Aborted


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void ffree(char **pp)
{
    if (!pp)
        return;

    char **a = pp;

    while (*pp) {
        free(*pp);  // Free the memory pointed to by pp
        pp++;       // Move to the next pointer
    }

    free(a); // Finally, free the memory for the array of pointers
}

int main() {
    char *str1 = strdup("Hello");
    char *str2 = strdup("World");
    
    char *arr[] = {str1, str2};

    ffree(arr);

    return 0;
}

in the simple code snippet above I'm writing my own array of strings free function where I free the pointer to an array of strings

Is there something wrong with my code?


Solution

  • There are several errors in your program:

    First of all, you need to know that you can only free dynamically allocated memory (via malloc() for example), in your code you use strdup() which calls malloc().

    char *arr[] = {str1, str2}; is not dynamically allocated, you can't free it.

    Secondly, in C, double-dimensional character arrays are delimited by NULL. The following block of code therefore doesn't work, because in arr there is no NULL:

    while (*pp) {
        free(*pp);
        pp++;
    }
    

    For it to work, you need to add the NULL to the last "line" of your array:

    char *arr[] = {str1, str2, NULL};
    

    Also, the malloc() function can fail and you need to systematically check that it doesn't return NULL, at the risk of getting a segfault, so you should do the following:

    char *str1, *str2;
    
    if ((str1 = strdup("Hello") == NULL) {
        // Error handling
    }
    
    if ((str2 = strdup("World") == NULL) {
        // Error handling
    }
    

    Here is a corrected version of your code:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    void ffree(char **pp)
    {
        if (!pp)
            return;
    
        size_t i = 0;
    
        while (pp[i]) {
            free(pp[i]);
            i++;
        }
    
        free(pp);
    }
    
    int main(void) {
    
        char *str1 = strdup("Hello");
        char *str2 = strdup("World");
    
       if (!str1 || !str2) {
            if (str1) {
                free(str1);
            }
            if (str2) {
                free(str2);
            }
            return (-1)
       }
    
        char **arr = malloc(3 * sizeof(char *));
    
        if (!arr) {
            free(str1);
            free(str2);
            return (-1);
        }
    
        arr[0] = str1;
        arr[1] = str2;
        arr[2] = NULL;
    
        ffree(arr);
    
        return (0);
    }