1

假设我有这个功能:

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

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

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

4

1 回答 1

3

第一个片段不正确。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;
}

您可能会注意到arrand*arr_ptr具有相同的值,an​​d 也是size如此size_ptr。这意味着我们可以简单地分别用arrand替换and的所有实例。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_ptr)[i] = fib(i);使用 代替arr[i] = fib(i);。因此,您发布的第一个片段是不正确的。

于 2020-05-01T01:06:13.477 回答