假设我具有此功能:
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
的指针,该指针是指向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
具有相同的值,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_ptr)[i] = fib(i);
代替arr[i] = fib(i);
。因此,您发布的第一个代码段不正确。