Ошибка сегментации при доступе к позициям массива после перераспределения - PullRequest
1 голос
/ 01 мая 2020

Предположим, у меня есть эта функция:

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;       
}

Примечание: я студент, и это правильное разрешение, которое дал учитель.

Теперь, единственный способ, которым я могу сделать это работа такова:

    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;
    }

Предположительно, первый (учитель) правильный, а второй (мой) - нет, потому что я не делаю лишних шагов.

Я бы хотел знаете, почему он выдает ошибку сегментации, это должно быть сделано или функция написана хорошо?

1 Ответ

3 голосов
/ 01 мая 2020

Первый фрагмент неверен. ptAtr не указатель на целые числа; это указатель на другой указатель, *ptAtr, который является указателем на целые числа. Таким образом,

ptArr[i] = fib(i);

должно быть

(*ptArr)[i] = fib(i);

Альтернативное объяснение

Довольно просто увидеть, что следующий код достигает правильный результат:

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;
}

Вы можете заметить, что arr и *arr_ptr имеют одинаковое значение, как и size и size_ptr. Это означает, что мы можем просто заменить все экземпляры arr и size на *arr_ptr и *size_ptr соответственно.

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;
}

Обратите внимание, что вместо arr[i] = fib(i); используется (*arr_ptr)[i] = fib(i);. Поэтому первый опубликованный вами фрагмент неверен.

...