-2

I'm writing a program to find the max and mix value of a int array, and I', trying to avoid using a int to track the current position, but the program keeps throwing segfault 11. It won't go through the loop. What's the reason?

/* Finds the largest and smallest elements in an array */
#include <stdio.h>
#define N 10

void max_min(int a[], int n, int *max, int *min);

int main(void){
int b[N], i, *big, *small;
printf("Enter %d numbers: ", N);
for (i = 0; i < N; i++)
   scanf("%d", &b[i]);
max_min(b, N, big, small);
printf("Largest: %d\n", *big);
printf("Smallest: %d\n", *small);
return 0;
}

void max_min(int a[], int n, int *max, int *min){
    int *p;
    *max = *min = *p = a[0]; 
    while (*p != EOF) {
        if (*p > *max)
           max = p;
        else if (*p < *min)
           min = p;
        p++;
    } 
}
Zhou
  • 31
  • 3

2 Answers2

0

Okay, there were a few bugs. I've produced two versions. One annotated with the bugs and a second with things cleaned up.

Here's the annotated version [please pardon the gratuitous style cleanup]:

/* Finds the largest and smallest elements in an array */
#include <stdio.h>
#define N 10

void max_min(int a[], int n, int *max, int *min);

int
main(void)
{
    int b[N],
     i,
    *big,
    *small;

    printf("Enter %d numbers: ", N);
    for (i = 0; i < N; i++)
        scanf("%d", &b[i]);

    // BUG1: big/small have not been initialized to point to anything
    max_min(b, N, big, small);

    printf("Largest: %d\n", *big);
    printf("Smallest: %d\n", *small);

    return 0;
}

void
max_min(int a[], int n, int *max, int *min)
{
    int *p;

    // BUG2: because of BUG1 above, this will segfault
    // BUG3: because p is never initialized, dereferencing it (via "*p") will
    // segfault
    *max = *min = *p = a[0];

    // BUG4: this will run past the end of the "a" array because there is
    // no guarantee of a matching sentinel value (i.e. EOF/-1)
    // in fact, using a sentinel is wrong because the "a" array can have _any_
    // value (i.e. there is _no_ sentinel value that can be used)
    while (*p != EOF) {
        // BUG5: when max or min gets set, we're changing what they point to
        // but this will _not_ change caller's values
        if (*p > *max)
            max = p;
        else if (*p < *min)
            min = p;
        p++;
    }
}

Here's a cleaned up and working version. In particular, note the change of big/small in main from int * to int with a corresponding change in the call to max_min:

/* Finds the largest and smallest elements in an array */
#include <stdio.h>
#define N 10

void max_min(int a[], int n, int *max, int *min);

int
main(void)
{
    int b[N],
     i,
    big,
    small;

    printf("Enter %d numbers: ", N);
    for (i = 0; i < N; i++)
        scanf("%d", &b[i]);

    max_min(b, N, &big, &small);

    printf("Largest: %d\n", big);
    printf("Smallest: %d\n", small);

    return 0;
}

void
max_min(int a[], int n, int *max, int *min)
{
    int *p;
    int val;

    p = &a[0];
    *max = *min = *p;

    for (int i = 0;  i < n;  ++i, ++p) {
        val = *p;
        if (val > *max)
            *max = val;
        else if (val < *min)
            *min = val;
    }
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
-3

In line two of max_min change your code to

max = min = p = a;

Memory's like a long row of lockers. When you declare int *max;, the variable max simply contains a locker number, the variable *max contains everything in this locker (which in this case is an int). An array is like a big row of lockers, a[0] is locker number a+0, a[1] is locker number a+1, and so on. You want to give p the value of a so when you increment it you get the next array index.

Robert
  • 203
  • 1
  • 9
  • that would assign the same memory location to all of them, which would mean that later in that function, when he is trying to give them different values, he'll need to create a new memory location for each of those pointers. – engineer14 Jun 30 '16 at 01:52
  • If you look at his assignment, he writes `max = p`. max and min will simply point to the max and min values in the array. Although after returning, big and small won't have changed at all, so I guess I did mess that up – Robert Jul 01 '16 at 00:40