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?

3
  • 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. Commented May 1, 2020 at 0: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? Commented May 1, 2020 at 0:53
  • @RetiredNinja oh.. i see what you mean, no that's my bad, will edit the question. But still without that it seg faults Commented May 1, 2020 at 1:07

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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!
woops, there was a missing not and a missing * in my explanation. wow. Fixed!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.