Search code examples
clistfor-loopfree

Free list of integers


I was trying to free a list of integers starting from the head and knowing how many elements are in the list, but I am getting an invalid pointer error. The code is the following:

int* factors = job_factorization(number, size);
printf("Thread %d: job terminated. Result: ", params->thread_id);
int* tmp;
for (int i = 0; i < *size; i++){
    printf("%d ", *factors);
    tmp = factors;
    factors++;
    free(tmp);
}

int *job_factorization(int number, int *size) {
    int *factors;
    int array_size = SIZE_INCREASE;
    int factor = 2;

    if (number < 2)
        return NULL;

    factors = (int *) malloc(sizeof(int) * SIZE_INCREASE);
    *size = 0;

    while (number != 1) {
        // check whether the number is divisible by the factor
        if (number % factor == 0) {
            // if there is no more space available, resize the array
            if (*size == array_size) {
                array_size += SIZE_INCREASE;
                factors = (int *) realloc(factors, sizeof(int) * array_size);
            }
            // add the factor to the list of prime factors
            factors[*size] = factor;
            (*size)++;
            number = number / factor;
        }
        else {
            // if not a factor, move to the next prime number
            factor = next_prime(factor);
        }
    }
    return factors;
}

Does anyone have any idea of the reason why this is happening? I have no clue about it (the function job_factorization works correctly)


Solution

  • job_factorization makes one malloc (and a number of reallocs). To the user of job_factorization this looks like one allocation only and that only needs one free. Like this:

    int* factors = job_factorization(number, size);
    
    for (int i = 0; i < *size; i++) {
        printf("%d ", factors[i]);     // don't increase factors in the loop
    }
    
    free(factors);                     // one free
    

    When you use realloc it replaces the old allocation, so if you first malloc for 1 element, then realloc for 2 elements, the result is one allocation with 2 elements - which requires one free only.