When we pass an element of an array to a function, it is treated as an normal variable and the called function creates a copy of the actual argument and operates on it. Any changes made in the formal arguments doesn't affect the actual arguments.
But this not the case when we pass a whole array. In this case it (called function) gets access to the actual arguments and any changes made in the formal arguments affects the actual arguments. Why this happens?
The array is passed as a pointer to the elements.
If I write:
void doStuff(int *ptr)
{
ptr[1] = 5;
}
int main()
{
int arr[] = {0, 1, 2};
doStuff(arr);
printf("%d %d %d\n", arr[0], arr[1], arr[2]);
}
the output will be "0 5 2". That's because C passes whatever is actually the parameter by value. The parameter is a pointer to an int. So a pointer to an int is passed by value. Thus, doStuff gets a copy of a pointer to memory in main's stack frame. When it dereferences that pointer with ptr[1]
, it is following the pointer to main's memory and modifying the array there.
C can only pass by value, but it does so "shallowly". If you ask it to pass an int *, it will pass an int *. It only copies the value of the pointer, not the values of anything it points to.
If you want doStuff to get its own copy of the array, either wrap the array in a struct as others have suggested, or use memcpy to manually deep copy the array like this:
void doStuff(int *ptr, int nElems)
{
int myCopyOfTheArray[nElems];
memcpy(myCopyOfTheArray, ptr, sizeof(int) * nElems);
/* do stuff with the local copy */
}
Unlike using a struct, the memcpy approach works if nElems is only know at runtime.
Arrays can't be passed by value in C. They get demoted to pointers. So the called function sees a pointer to the array (passed by reference) and operates on it. If you want to make a copy, you have to either do so explicitly, or put your array inside a struct (which can be passed by value to functions.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With