【问题标题】:Segmentation Fault accessing array positions after realloc重新分配后访问数组位置的分段错误
【发布时间】:2020-08-15 12:19:13
【问题描述】:

假设我有这个功能:

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

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

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

【问题讨论】:

  • 一般来说第一个不好。这些变量的命名会导致一些令人困惑的范围问题。你的更好,但你忘记检查realloc 的结果是否为NULL
  • 第一个功能是教师?这是不对的。您确定 ptArr 在函数内部再次声明为局部变量吗?
  • @RetiredNinja 哦.. 我明白你的意思,不,那是我的错,将编辑问题。但仍然没有它,它会出现故障

标签: c memory-management segmentation-fault realloc memory-reallocation


【解决方案1】:

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

【讨论】:

  • 非常感谢您花时间解释!想象一下,支付学费后仍然需要求助于在线社区,因为有些老师不会只是承认自己错了……再次感谢!
  • 糟糕,我的解释中缺少not*。哇。固定!
猜你喜欢
  • 2017-09-08
  • 2017-12-13
  • 2021-10-11
  • 2018-05-15
  • 2019-09-16
  • 1970-01-01
  • 2020-04-09
  • 2012-11-01
  • 2013-02-17
相关资源
最近更新 更多