重新分配后访问数组位置的分段错误
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
具有相同的值,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);
。因此,您发布的第一个片段不正确。
假设我有这个功能:
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
具有相同的值,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);
。因此,您发布的第一个片段不正确。