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 chan
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.