Search code examples
cmemory-managementmallocdynamic-memory-allocationrealloc

Why does free() cause an error in my code when it's there, but everything runs well when it is not there?


My program takes an arbitrary number of words at runtime and stores them in a dynamically-sized array of words.

Currently, my program runs well, except when I use free() to free up the memory of the temporary double pointer temp. I am not quite sure why it does this, as I thought it would cause errors if I didn't use it.

int wordSize = 10, arrSize = 1, i = 0;
char **stringArr, **temp;
char *input;

stringArr = malloc(arrSize * sizeof(char *));

puts("Accepting input...");

for (;;) {
    if (i >= arrSize) {
        arrSize += 1;
        temp = realloc(stringArr, arrSize * sizeof(char *));

        if (temp != NULL) {
            stringArr = temp;
            free(temp); // This is the line that is giving me issues; removing it works
        } else {
            puts("Could not allocate more memory");
            return 0;
        }
    }

    stringArr[i] = malloc(sizeof(input));
    input = malloc(wordSize * sizeof(char));
    scanf("%10s", input);

    if (strcmp(input, "END")) {
        strcpy(stringArr[i], input);
        i++;
    } else
        break;
       
}
free(stringArr);

At the bottom of my program I use free() without any issues. How come it works OK here but not earlier on in the program.

I feel I am missing something about how free() works.

Note: this is my first program implementing malloc() and realloc(), so I am only just getting used to how they work. If you know of a better way to accomplish what I am doing that, please feel free to describe.


Solution

  • The free(temp); line is causing an error (later on) because, in the preceding line, stringArr = temp;, you are assigning the address that is stored in the temp pointer to that in the stringArr pointer. Thus, when you free the memory pointed to by temp you also free the memory pointed to by stringArr, because it is the same memory block. Copying a pointer's value from one variable to another does not make a (separate) copy of the memory.

    Omitting the free(temp); line is correct, because that memory is freed later on, in the free(stringArr); call.