双指针使用错误

时间:2015-01-11 18:20:13

标签: c

练习双指针时遇到麻烦 错误是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指向的变量!

但我现在遇到访问错误..我会感谢您的帮助!

4 个答案:

答案 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中的minptrmain()指向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。 请记住,根据您使用的环境(操作系统,版本,编译器,标准),程序结果可能会有所不同。