重新分配后访问数组位置的分段错误

Segmentation Fault accessing array positions after realloc

假设我有这个功能:

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

据说第一个(老师的)是正确的,第二个(我的)不是因为我做了不需要的额外步骤。

我想知道为什么它会抛出分段错误,它应该这样做还是函数写得好?

第一个片段不正确。 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 具有相同的值,sizesize_ptr 也是如此。这意味着我们可以简单地将 arrsize 的所有实例分别替换为 *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_ptr)[i] = fib(i); 而不是 arr[i] = fib(i);。因此,您发布的第一个片段不正确。