cdynamic-memory-allocationrealloccalloc

"double free detected in tcache 2" Error while reallocating a pointer to a dynamic array of strings


I have written this code to store a dynamic array of strings on which different operations can be performed. It works correctly when I enter the strings initially and when I add 2 strings, but on the 3rd string it fails each time with the error "free(): double free detected in tcache 2". I haven't freed memory anywhere in the program, so i don't understand why this error is occurring. Also from what I saw after searching about this error, it occurs when the program attempts to free a memory location that has been freed earlier.

The error is occurring due to the realloc statement in the addend() function. But I am unable to grasp what is actually going wrong.

Can someone give a hint as to what I might be doing wrong here. Thanks!

#include <stdio.h>
#include <stdlib.h>

void addend(char** arr,int size) {
    arr = (char **) realloc(arr, (size+1)*sizeof(char *));
    *(arr+size) = (char *) calloc(100, sizeof(char));

    printf("Enter new string to be added : ");
    scanf("%s",*(arr+size));
}

void addbegin(char** arr,int size) {
    arr = (char **) realloc(arr, (size+1)*sizeof(char *));
    for (int i = size; i>0; i--) {
        *(arr+i) = *(arr+i-1);
    }
    printf("Enter new string to be added : ");
    scanf("%s",*(arr));
}

void printarr(char** arr, int size) {
    printf("[");
    for (int i = 0; i<size; i++) {
        printf("%s, ",*(arr+i));
    }
    printf("]\n");
}

void delete() {}

int main() {
    int n;
    printf("Enter the size of the array : ");
    scanf("%d",&n);

    char** arr = (char **) calloc(n,sizeof(char*));

    for(int i=0; i<n; i++) {
        *(arr+i) = (char *) calloc(100, sizeof(char));
    }

    for (int i = 0; i<n; i++) {
        printf("Enter the (%d) string to be entered : ",i);
        scanf("%s",*(arr+i));
    }

    int option;
    for (;;) { 
        printf("Choose out of the following options: Add End (1), Add Beginning (2), Delete (3), Length (4), Print Array (5) : ");
        scanf("%d",&option);

        switch(option) {
            case 1:
                addend(arr,n);
                n++;
                break;
            case 2:
                addbegin(arr,n);
                n++;
                break;
            case 3:
                delete();
                break;
            case 4:
                printf("%d",n);
                break;
            case 5:
                printarr(arr,n);
                break;
            default:
                printf("Invalid option, enter again\n");
        }
    }
}

Solution

  • void addend(char** array,int size) {
       array = (char **) realloc(array, (size+1)*sizeof(char *));
       /* ... */
    

    It does not change the arr from the main function as array (I changed the name intentionally to make a clear distinction between those two variables) is a local variable in the addend function scope.

    You need to pass the reference to the arr to be able to modify it.

    void addend(char*** array,int size) {
       *array = realloc(*array, (size+1)*sizeof(**array));
       /* ... */
    

    And in the main function addend(&arr,n);.

    You need to amend all other functions (and calls to them) you made the same mistake.

    Side notes:

    1. You use realloc incorrectly. You need to save the result to the temporary variable as realloc may fail and you will have a memory leak (as you will not have reference to the previously allocated memory)
    2. Do not cast the result of malloc and friends. If it does not compile it means that you are compiling C code using C++ compiler and it is not correct.