练习双指针时遇到麻烦 错误是Xcode中的“EXE_BAD_ACCESS”
#include <stdio.h>
/* Program to Get Min and Max Value
in Array */
void SaveValue(int **maxPtr, int **minPtr, int arr[])
{
int i;
**maxPtr=arr[0]; // Error Line
**minPtr=arr[0]; // Error Line
for(i=1; i<5; i++)
{
if(arr[i]>**maxPtr)
**maxPtr=arr[i];
else if(arr[i]<**minPtr)
**minPtr=arr[i];
}
}
int main()
{
int arr[5]={4, 5, 7, 2, 6};
int *maxptr;
int *minptr;
SaveValue(&maxptr, &minptr, arr);
printf("%d, %d \n", *maxptr, *minptr);
}
我认为*dptr
的{{1}}是**dptr = &ptr
和*ptr
表示**dptr
指向的变量。
所以我假设*ptr
表示通过引用保存第一个**dptr = arr[0]
数arr
指向的变量!
但我现在遇到访问错误..我会感谢您的帮助!
答案 0 :(得分:2)
void SaveValue(int **maxPtr, int **minPtr, int arr[]);
提供指向int
的指针,因此请使用它们。
void SaveValue(int **maxPtr, int **minPtr, int arr[])
{
int i;
*maxPtr=arr + 0; /* same as *maxPtr = &arr[0]; */
*minPtr=arr + 0; /* same as *maxPtr = &arr[0]; */
for(i = 1; i < 5; i++)
{
if(arr[i] > **maxPtr)
*maxPtr = arr + i; /* same as *maxPtr = &arr[i]; */
else if(arr[i] < **minPtr)
*minPtr = arr + i; /* same as *minPtr = &arr[i]; */
}
}
此界面也有点危险且不灵活;那么为什么不传递数组的大小:
void SaveValue(int **maxPtr, int **minPtr, int arr[], ssize_t s)
{
*maxPtr=arr + 0;
*minPtr=arr + 0;
for(--s; s >= 0; --s)
{
if(arr[s] > **maxPtr)
{
*maxPtr = arr + s;
}
else if(arr[i] < **minPtr)
{
*minPtr = arr + s;
}
}
}
像这样调用fcuntion:
SaveValue(&maxptr, &minptr, arr, sizeof arr/sizeof *arr);
由于函数的返回值未使用,我们可以使用它来应用一些错误信息,以允许函数的用户编写更稳定的代码:
int SaveValue(int ** maxPtr, int ** minPtr, int arr[], ssize_t s)
{
int result = 0;
if ((NULL == arr) || (NULL == maxPtr) || (NULL == minPtr) || (0 > s))
{
result = -1;
errno = EINVAL;
}
else
{
*maxPtr=arr + 0;
*minPtr=arr + 0;
for(--s; s >= 0; --s)
{
if(arr[s] > **maxPtr)
{
*maxPtr = arr + s;
}
else if(arr[i] < **minPtr)
{
*minPtr = arr + s;
}
}
}
return result;
}
像这样使用:
#include <stdio.h>
int SaveValue(int ** maxPtr, int ** minPtr, int arr[], ssize_t s);
int main(void)
{
int arr[5]={4, 5, 7, 2, 6};
int *maxPtr;
int *minPtr;
int result = SaveValue(&maxPtr, &minPtr, arr, sizeof arr/sizeof *arr);
if (-1 == result)
{
perror("SaveValue() failed")
}
else
{
printf("%d, %d \n", *maxPtr, *minPtr);
}
}
答案 1 :(得分:1)
指针应该在取消引用之前指向有效的内存位置,否则会导致未定义的行为。以下更改将修复您的错误。
int max;
int min;
int *maxptr = &max;
int *minptr = &min;
这里不需要双指针将函数原型更改为
void SaveValue(int *maxPtr, int *minPtr, int arr[])
有
int max;
int min;
main()
中的并相应地调用此API
SaveValue(&max,&min,arr);
答案 2 :(得分:0)
我假设您的代码纯粹用于指针学习目的,而不是在实际情况下尝试实现此操作。因此,如果您希望maxptr
中的minptr
和main()
指向arr[]
中的最大值和最小值,我认为您应该更改{{1}中的双指针赋值到**maxPtr=arr[0]
,所以你的代码将成为:
*maxPtr=&arr[0]
在这种情况下,当您进行分配时,您不希望取消引用双指针。相反,在main()中取消引用它们时,应该为它指定要显示的元素的地址。
答案 3 :(得分:-1)
在初始化函数SaveValue中的maxPtr和minPtr指针时,不需要在for循环体中使用双星号。 MaxPtr和minPtr都是双指针,但仍然是main()中maxptr的内存方向。因此,您只需要使用单个星号取消引用它们,以访问它们指向的内存方向。 源代码正确如下:
#include <stdio.h>
/* Correct program to Get Min and Max Value in Array */
void SaveValue(int **maxPtr, int **minPtr, int arr[])
{
int i;
*maxPtr=arr[0];
*minPtr=arr[0];
for(i=1; i<5; i++)
{
if(arr[i]>*maxPtr)
*maxPtr=arr[i];
else if(arr[i]<*minPtr)
*minPtr=arr[i];
}
}
int main(void)
{
int arr[5]={4, 5, 7, 2, 6};
int *maxptr;
int *minptr;
SaveValue(&maxptr, &minptr, arr);
printf("%d, %d \n", maxptr, minptr);
return 0;
}
当我用GCC编译并执行它时,我得到下一个输出: 7,2。 请记住,根据您使用的环境(操作系统,版本,编译器,标准),程序结果可能会有所不同。