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

问题描述 投票:1回答: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;
    }

应该第一个(老师的)是正确的,第二个(我的)不是,因为我不需要执行额外的步骤。

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

c memory-management segmentation-fault realloc memory-reallocation
1个回答
3
投票

第一个代码段不正确。 ptAtr不是指向整数的指针;它是指向另一个指针*ptAtr的指针,该指针是指向int的指针。因此,

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);。因此,您发布的第一个代码段不正确。

© www.soinside.com 2019 - 2024. All rights reserved.