Home > Net >  C - value changed in function doesn't change in main() despite using pointers
C - value changed in function doesn't change in main() despite using pointers

Time:09-11

The function row_stats is supposed to update the value stored by variable max_ptr with maximum number from a given row of the array. I tried looking it up in other questions here but it didn't help. Could someone please explain me where is the mistake?

#include <stdio.h>

void row_stats(int(*ptr)[5], int width, int row_id, int* max) {
    int i = 0;
    int curr = ptr[row_id][0];

    while (i < width) {
        if (ptr[row_id][i] > curr) {
            curr = ptr[row_id][i];
        }

        i  ;
    }
    max = &curr;
    printf("max: %d\n", *max);
}

int main() {
    int a[5][5] = {
        {1, 2, 3, 4, 5},
        {6, 7, 8, 9, 10},
        {11, 12, 13, 14, 15},
        {16, 17, 18, 19, 20},
        {21, 22, 23, 24, 25}
    };

    int* max_ptr;
    row_stats(a, 5, 3, max_ptr);
    printf("after funct: %d", *max_ptr);

    return 0;
}

CodePudding user response:

In the function, max can be set to point to an array index. To do that, int **max is needed and pass the address of the pointer to the function.

#include <stdio.h>

void row_stats(int(*ptr)[5], int width, int row_id, int** max) {
    int i = 0;
    *max = &ptr[row_id][0]; // points to an array element
    while (i < width) {
        if (ptr[row_id][i] > **max) {
            *max = &ptr[row_id][i]; // points to an array element
        }
        i  ;
    }
    printf("max: %d\n", **max);
}
int main(void) {
    int a[5][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};
    int* max_ptr;
    row_stats(a,5,3,&max_ptr); // pass address of pointer
    printf("after funct: %d\n", *max_ptr);
    return 0;
}

CodePudding user response:

max = &curr;

semantically makes no sense. max is a local copy of the max_ptr from main, you are changing the copy to point to a local variable. Both the pointer copy and the local variable are discarded on return.

You need to modify what max points to thus:

*max = curr ;

However in this case it points to nothing defined. In main you need also need to change:

int* max_ptr;
row_stats(a, 5, 3, max_ptr);

to

int max ;
row_stats(a, 5, 3, &max ) ;

&max is a pointer to max.

All that said, in this case the use of a reference parameter is ill advised if you only wish to return an int and are not already using the return value for something else. The safer and simpler method would be to simply return the value:

int row_stats( int(*ptr)[5], int width, int row_id ) 
{
    ...    
    return curr ;
}

then

int max = row_stats( a, 5, 3 ) ;

CodePudding user response:

    max = &curr;

Sets max to point to a variable inside the function. Did you mean

    *max = curr;
    int* max_ptr;
    row_stats(a, 5, 3, max_ptr);

But it was never initialized so it ponts into somewhere arbitrary. Anything can happen.

It's like you meant:

    int max;
    int* max_ptr = &max;
    row_stats(a, 5, 3, max_ptr);

There's ways to simplify the code but it looks like an exercise so I'm going with this.

CodePudding user response:

There are two things, you must change.

First, you should pass an address to an int, not a pointer, e.g.

int max;
row_stats(a, 5, 3, &max);
printf("after funct: %d", max);

and then you must return the maximum value. Not by assigning the address of a local variable to the local pointer parameter, but by assigning the maximum value to the integer stored outside of row_stats:

*max = curr;
  •  Tags:  
  • c
  • Related