medbot
medbot

Reputation: 46

Inconsistent array values when initialized from fscanf() in C

If a multi-dimensional array in main() gets initialized from a functions pointer like this:

#include <stdio.h>

void arrayfunction(int (*n)[3][3])
{

(*n)[0][2]=7;

printf("Function output: %i\n", *n[0][2]);

}

main()
{

int y[3][3];

arrayfunction(&y);

printf("Main output: %i \n",y[0][2]);

return(0);

}

then array in main() will hold the correct value, but the output from the pointer in arrayfunction() will not:

Function output: 4195805
Main output: 7 

However, if the function initializes the array in main() through the functions pointer via fscanf():

#include <stdio.h>

void readSchedule(int (*s)[3][3]){


FILE *schedule;





schedule=fopen("/var/schedule.conf","r");      

fscanf(schedule,"[%i,%i,%i,%i]\n",s[0][0], s[0][1], s[0][2], s[0][3]); 

fclose(schedule); 

printf("Function output value: %i\n",*s[0][2]);

}

main()
{
int x[3][3];


readSchedule(&x);

printf("Main output value: %i\n ",x[0][2]);

return(0);

}

Then the values are reversed, the pointer local to the function will output the correct value, but the array it points to in main() will not:

Function output value: 7
Main output value: 0

Why do the correct values only show up in the array local to main() in the first example, but only show up in the pointer local to the function in the second example?

Upvotes: 2

Views: 60

Answers (2)

medbot
medbot

Reputation: 46

The problem in the first example is solved in the syntax of the pointer to array argument in the printf statement inside the function by changing the precedence from:

printf("Function output: %i\n", *n[0][2]);

to

printf("Function output: %i\n", (*n)[0][2]);

In the second example, fscanf() was apparently stuffing values directly into *s[][] instead of indirectly initializing the array in main() that *s[][] points to. So instead of this:

fscanf(schedule,"[%i,%i,%i,%i]\n",s[0][0], s[0][1], s[0][2], s[0][3]);

the syntax needs to be this:

fscanf(schedule,"[%i,%i,%i,%i]\n",&(*s)[0][0], &(*s)[0][1], &(*s)[0][2], &(*s)[0][3]);

in order to reach through *s[][] and place the values in y[][].

Upvotes: 1

Michael Albers
Michael Albers

Reputation: 3779

Check the operator precedence and notice the difference in the two lines using n in arrayFunction

(*n)[0][2]=7;
printf("Function output: %i\n", *n[0][2]);

The parenthesis are critical here. The [] operator has a higher precedence than * (http://en.cppreference.com/w/cpp/language/operator_precedence). If you add parenthesis in the printf line you'll see what you expect.

More or less the same thing is going on in with the fscanf example. The compiler is treating s[0][0] as a pointer to an int (like this *(s[0][0])) so the data is getting written to an undefined area.

If you use a memory debugging program like valgrind you'll see tons of errors.

Upvotes: 1

Related Questions