Home > Net >  C - after going to main() one variable changes its value and another, initialised in the same way, w
C - after going to main() one variable changes its value and another, initialised in the same way, w

Time:09-11

The pointers to max and min values are initialised exactly the same, yet there is some error which causes the min value to be set to some huge number (a value of memory adress or maximum possible value maybe?). My question is - how is that possible and what can I do to fix it? I will be grateful for your help.

#include <stdio.h>

int row_stats(int(*ptr)[5], int width, int height, int row_id, int** max, int** min, float** avg)
{
    *max = &ptr[row_id][0];
    for(int i=0;i<width;i  )
    {
        if(ptr[row_id][i]>**max)
        {
            *max = &ptr[row_id][i];
        }
    }

    *min = &ptr[row_id][0];
    for(int i=0;i<width;i  )
    {
        if(ptr[row_id][i]<**min){
            *min = &ptr[row_id][i];
        }
    }
    // At this point, the value of **min is correct and equal to 16
    *avg = &ptr[row_id][0]; // I know the types are conflicting here but if I delete it, the max and avg values stop showing.
    int sum = 0;
    for(int i=0;i<width;i  )
    {
        sum = sum ptr[row_id][i];
    }
    **avg = sum/width;

}
int main() {
    int* max_ptr;
    int* min_ptr;
    float* avg_ptr;
    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}};

    row_stats(a,5,5,3,&max_ptr,&min_ptr,&avg_ptr);
    printf("MAX: %d\n", *max_ptr); //here the value pointed by max_ptr is correct (20)
    printf("MIN: %d\n", *min_ptr); //here the value pointed by min_ptr is 1099956224
    printf("AVG: %f\n", *avg_ptr);
    return 0;
}

CodePudding user response:

You seem to be struggling with pointers. For example, if you want to return the average as a float parameter in a function, then you reserve the float variable and pass its address like this

void calc_avg(float *avg_ptr)
{
    int sum = 49;
    int width = 5;
    *avg_ptr = ((float)sum) / width; 
}

int main()
{
    float avg;
    calc_avg(&avg);
    printf("AVG: %f\n", avg);
    return 0;
}

Also, the following equation will be calculated in integer arithmetic, and as a result, will loose the fraction part:

 **avg = sum/width;

You need to change it to:

 *avg_ptr = ((float)sum) / width;

You can do similar fixes for min and max.

CodePudding user response:

In the function the int pointers can be set to point to array elements but there isn't a valid float for the float pointer.
The average could be returned.

#include <stdio.h>

float row_stats(int(*ptr)[5], int width, int height, int row_id, int** max, int** min)
{
    *max = &ptr[row_id][0];
    for(int i=0;i<width;i  )
    {
        if(ptr[row_id][i]>**max)
        {
            *max = &ptr[row_id][i];
        }
    }

    *min = &ptr[row_id][0];
    for(int i=0;i<width;i  )
    {
        if(ptr[row_id][i]<**min){
            *min = &ptr[row_id][i];
        }
    }
    // At this point, the value of **min is correct and equal to 16
    // *avg = &ptr[row_id][0]; // I know the types are conflicting here but if I delete it, the max and avg values stop showing.
    int sum = 0;
    for(int i=0;i<width;i  )
    {
        sum = sum ptr[row_id][i];
    }
    // **avg = sum/width;
    return (float)sum/width;
}
int main() {
    int* max_ptr;
    int* min_ptr;
    float avg;
    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}};

    avg = row_stats(a,5,5,3,&max_ptr,&min_ptr);
    printf("MAX: %d\n", *max_ptr); //here the value pointed by max_ptr is correct (20)
    printf("MIN: %d\n", *min_ptr); //here the value pointed by min_ptr is 1099956224
    printf("AVG: %f\n", avg);
    return 0;
}

Pass the address of memory defined in main:

#include <stdio.h>

void row_stats(int(*ptr)[5], int width, int height, int row_id, int** max, int** min, float *avg_ptr)
{
    *max = &ptr[row_id][0];
    for(int i=0;i<width;i  )
    {
        if(ptr[row_id][i]>**max)
        {
            *max = &ptr[row_id][i];
        }
    }

    *min = &ptr[row_id][0];
    for(int i=0;i<width;i  )
    {
        if(ptr[row_id][i]<**min){
            *min = &ptr[row_id][i];
        }
    }
    // At this point, the value of **min is correct and equal to 16
    // *avg = &ptr[row_id][0]; // I know the types are conflicting here but if I delete it, the max and avg values stop showing.
    int sum = 0;
    for(int i=0;i<width;i  )
    {
        sum = sum ptr[row_id][i];
    }
    // **avg = sum/width;
    *avg_ptr = (float)sum/width;
}
int main() {
    int* max_ptr;
    int* min_ptr;
    float avg = 0.0;
    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}};

    row_stats(a,5,5,3,&max_ptr,&min_ptr, &avg);
    printf("MAX: %d\n", *max_ptr); //here the value pointed by max_ptr is correct (20)
    printf("MIN: %d\n", *min_ptr); //here the value pointed by min_ptr is 1099956224
    printf("AVG: %f\n", avg);
    return 0;
}
  •  Tags:  
  • c
  • Related