1

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?

walkman
  • 478
  • 1
  • 8
  • 21
  • 2
    that first one's bad in general. The naming of those variables causes some scope issues that are confusing. Yours is better but you forget to check if the result of `realloc` is `NULL`. – S.S. Anne May 01 '20 at 00:52
  • 4
    The first function is the teachers? It's wrong. Are you sure that `ptArr` is declared again as a local inside the function? – Retired Ninja May 01 '20 at 00:53
  • @RetiredNinja oh.. i see what you mean, no that's my bad, will edit the question. But still without that it seg faults – walkman May 01 '20 at 01:07

1 Answers1

3

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.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I'm really thankful for the extra time explaining! Imagine paying tuition and still need to resort to an online community because some teachers won't just admit they're wrong... Once again, thanks! – walkman May 01 '20 at 01:24
  • woops, there was a missing `not` and a missing `*` in my explanation. wow. Fixed! – ikegami May 01 '20 at 01:42