For the following C program:
#include <stdio.h>
#include <stdint.h>
int64_t* newCopy(void* array, size_t newElements)
{
int64_t newArray[newElements];
for (size_t i = 0; i < newElements; i++) {
newArray[i] = ((int64_t*)array)[i];
}
int64_t* ptr = &newArray;
return ptr;
}
int main() {
int64_t array[3] = {1,2,3};
int64_t* copy = newCopy(array,3);
array[1] = 4;
for (size_t i = 0; i<3;i++){
printf("%ld\n",copy[i]);
}
}
Returning newArray as itself for the function newCopy causes Segmentation Fault. Yet the function runs well if I create a new pointer variable ptr and assign the array into it.
As arrays are pointers then shouldn't returning it as it be okay?
This has nothing specific to do with array type.
The variable in discussion here, newArray
is local to the scope of the function, and its lifetime is till the function execution scope. Once the function execution has finished and the control returns to the caller, all the memory locations allocated inside the function are invalid.
Attempt to use invalid memory will invoke undefined behaviour, including but not limited to a segmentation fault.
As a solution, you can use allocator functions malloc()
and family to allocate memory, captured in a pointer variable, and return that from the function, as the lifetime of the allocated memory is either until deallocation or the entire program lifetime, whichever is earlier.
Or you can also pass an array reference from the calling routine, so the function is not given the responsibility of acquiring the needed storage for something that goes further its control. This allows you to decide how to allocate the new array.
/* if your array is going to operate on int64_t elements, better don't use void * as the type you pass in */
void newCopy(int64_t* array, int64_t *copy, size_t newElements)
{
for (size_t i = 0; i < newElements; i++) {
copy[i] = array[i];
}
}
(far simpler)