Reputation: 498
Let's suppose I have this function:
void arrayExtendDouble(int **ptArr, int *size)
{
*ptArr = realloc(*ptArr, (*size * 2) * sizeof(int));
for(int i = (*size * 2) - 1; i >= *size; i--)
ptArr[i] = fib(i); //this will throw SEG FAULT
*size *= 2;
}
Note: I am a student and this is the valid resolution a teacher gave.
Now, the only way i can make this work is like this:
void fibArrayExpand(int **ptArr, int *size)
{
int *ptArrNew = realloc(*ptArr, (*size * 2) * sizeof(int));
for(int i = (*size * 2) - 1; i >= *size; i--)
ptArrNew[i] = fib(i);
*size *= 2;
*ptArr = ptArrN;
}
Supposedly the first one (teacher's) is correct and the second one (mine) it's not because i do extra steps not needed.
I would like to know why does it throw segmentation fault, is it supposed to do so or is the function well written?
Upvotes: 1
Views: 70
Reputation: 385590
The first snippet isn't correct. ptAtr
isn't the pointer to the ints; it's a pointer to another pointer, *ptAtr
, which is the pointer to the ints. As such,
ptArr[i] = fib(i);
should be
(*ptArr)[i] = fib(i);
Alternate explanation
It's pretty easy to see the following code achieves the correct result:
void arrayExtendDouble(int** arr_ptr, int* size_ptr)
{
// Copy values from caller.
int* arr = *arr_ptr;
int size = *size_ptr;
arr = realloc(arr, (size * 2) * sizeof(int));
for(int i = (size * 2) - 1; i >= size; i--)
arr[i] = fib(i);
size *= 2;
// Pass back modified values to caller.
*arr_ptr = arr;
*size_ptr = size;
}
You might notice that arr
and *arr_ptr
have the same value, and so do size
and size_ptr
. That means we could simply replace all instances of arr
and size
with *arr_ptr
and *size_ptr
respectively.
void arrayExtendDouble(int** arr_ptr, int* size_ptr)
{
*arr_ptr = realloc(*arr_ptr, (*size_ptr * 2) * sizeof(int));
for(int i = (*size_ptr * 2) - 1; i >= *size_ptr; i--)
(*arr_ptr)[i] = fib(i);
*size_ptr *= 2;
}
Note that (*arr_ptr)[i] = fib(i);
is used instead of arr[i] = fib(i);
. The first snippet you posted is therefore incorrect.
Upvotes: 3