Search code examples
cmallocdynamic-memory-allocationmemcpyrealloc

C dynamicaly changing size of array using malloc and memcpy


I wanted to write a function that changes the size of dynamic array and allows user to fill it at once. I know that I should do it with using of "realloc" (so I did and so it works...) but my first attempt looked like this:

void ChangeDynamicArraySize(int* dArray, int oldSize, int newSize){

    int* tempArray = (int*) malloc(sizeof(int) * oldSize);
    CopyArray(tempArray, dArray, oldSize);
    free(dArray);
    dArray = (int*) malloc(sizeof(int) * newSize);
    CopyArray(dArray, tempArray, oldSize);

    for (int i = oldSize; i < newSize; i++){
        scanf("%i", &dArray[i]);
    }
    PrintArray(dArray, newSize);
    free(tempArray);
}

In function body "PrintArray(dArray, newSize);" worked correct. But when called from main() it gives a result like: - 17891602 - 17891602 - 17891602 - 17891602

So it looks like dArray was freed...? But as I know allocated memmory isn't automatically freed after exiting function.

Then what could be the reason?


Solution

  • In C, functions parameters are copied locally. Any change you make on the value dArray points to (*dArray) works, but any change you make on the (address of) dArray you passed as a parameter, is only local to this function, because it is a copy.

    You may want to pass the address of your array (a &array in your main, a dArray** in your function prototype) and make changes to the pointer instead.

    Something like this:

    void ChangeDynamicArraySize(int** dArray, int oldSize, int newSize){
    
        int* tempArray = (int*) malloc(sizeof(int) * oldSize);
        CopyArray(tempArray, *dArray, oldSize);
        free(*dArray);
        *dArray = (int*) malloc(sizeof(int) * newSize);
        CopyArray(*dArray, tempArray, oldSize);
    
        for (int i = oldSize; i < newSize; i++){
            scanf("%i", dArray[i]);
        }
        PrintArray(*dArray, newSize);
        free(tempArray);
    }
    

    Alternatively, you may also just return the address of your new malloced array (making your function return this int* instead of no value).

    Also, for good practices, you may want to not cast the return of malloc, and check whether it failed and changed ERRNO (if you use the POSIX API).