Search code examples
carraysdynamic-memory-allocationfree

free() in dynamic memory


Do I use correctly free() in the code below? Is it a memory leak? Is it a problem use free() in the main part and not in the function? If yes there is a method to free in the function and not in main?

This code copy an array in another one.

int *copy(const int *arr,int n);

int main(){
    int *p_arr1,*p_arr2;
    int n,i;

    printf("Insert size of array: ");
    scanf("%d",&n);

    p_arr1 = calloc(n,sizeof(int));

    for(i=0;i<n;i++){
        printf("Insert element %d of the array: ",i+1);
        scanf("%d",p_arr1+i);
    }

    p_arr2 = copy(p_arr1,n);

    for(i=0;i<n;i++){
        printf("%d ",*p_arr2);
        p_arr2++;
    }

    free(p_arr1);
    free(p_arr2);

    return 0;
}

int *copy(const int *arr,int n){
    int i;
    int *new;
    new = calloc(n, sizeof(int));
    for(i=0;i<n;i++){
        new[i] += arr[i];
    }

    return new;
}

Solution

  • As long as you have the pointer returned by malloc (or in your case calloc) you can pass it to free when and wherever you want, it doesn't have to be in the same function.

    However, after the loop where you print the contents of p_arr2, you no longer have the pointer returned by calloc inside the function, because you modify the pointer in the loop.

    You need to use a temporary pointer variable for the loop:

    int *p_arr2_tmp = p_arr2;
    for (size_t i = 0; i < n; ++i)
    {
        printf("%d ", *p_arr2_tmp);
        ++p_arr2_tmp;
    }
    
    // Now we can free the memory pointed to by the original p_arr2 pointer
    free(p_arr2);
    

    Or you could use simple array indexing instead:

    for (size_t i = 0; i < n; ++i)
    {
        printf("%d ", p_arr2[i]);
    }
    
    // The pointer p_arr2 wasn't modified, so it can be passed to free
    free(p_arr2);