9
// test.txt
50
13
124

-

void hi ( int *b, FILE *pfile ) {

    rewind ( pfile );
    int i;
    for( i = 0 ; i < 3 ; i++ ) {
         fscanf ( pfile, "%d", &b[i] );
    }
}

int main ( void ) {

    FILE *fp = fopen ( "test.txt", "r" );
    int a[10];  //putting extra size for test.

    hi ( &a[0], fp );   
    printf("%d,%d,%d\n", a[0], a[1], a[2]);

    fclose ( fp );
    return 0;
}

I'm trying to understand pointers when there's array involved. While I was testing the code above, I noticed that by putting a different index value such as hi ( &a[0], fp ) to hi ( &a[1], fp ) I get different results.

//result of [ hi ( &a[0], fp ) ] //result of [ hi ( &a[1], fp ) ] 50,13,124 junk#,50,13 .

I am really confused about the results because in the 'hi' function I specify the start of the array from i = 0 which should mean it's storing the value starting from a[0]. But it seems like putting 1 instead of 0 is somehow moving values aside. Why is this happening?

1
  • 1
    &b[i] is just b + i. If you pass in &a[0] (which is the same as a for the purpose of pointers), that becomes a + i. If you pass in &a[1], which is a + 1, it becomes a + 1 + i instead. Commented Aug 12, 2017 at 23:17

3 Answers 3

6

This might make more sense for you if you think of & as an operator which acts on a single item, much like - acts on a number to change the sign. In this case, & takes the address of whatever you give it. In the case of &a[0], you are taking the address of a[0]. In the case of &a[1], you take the address of a[1]. In other words, you take the address of different elements of the array. So in the function, b contains the address that you passed to it. As far as the function knows, what you pass in is the "first" element of the array. It knows nothing of any of the preceding elements.

Sign up to request clarification or add additional context in comments.

2 Comments

wow I get it now. Thank you for such a simple and easy-to-understand answer.
@ChewChew Glad I can help. Please read What should I do when someone answers my question?.
4

You are not 'puuting a different size' but providing a pointer to the 1st element in the array and then the 2nd element.

Since in the second case you gave a pointer to the 2nd element, and tried to read 10 elements (starting at the 2nd position) but only have 9 valid elements when starting at the 2nd one, you are then reading into memory that is not in the array.

Comments

4

In your second example you have an Undefined Behaviour. You pass the address of the second element of the array. Then you scanf all 10 elements. But because you passed the address of the second element as the initial one, the last scanf writes the element which is outside the array - and it is a mistake.

enter image description here

I would suggest if you go to manipulate more than element of the array, pass the size of the array as well

#define ARRAYSIZE(x)   (sizeof(x) / sizeof(x[0]))

void hi ( int *b, FILE *pfile, size_t size ) {

    rewind ( pfile );
    int i;
    for( i = 0 ; i < size ; i++ ) {
         fscanf ( pfile, "%d", &b[i] );
    }
}

and the call

hi ( a, fp, ARRAYSIZE(a));   

or

hi ( &a[0], fp, ARRAYSIZE(a));   

3 Comments

Great suggestion. Passing the size of an array is a good practice. Just be careful with the ARRAYSIZE macro as it will not give the correct results with &a[1].
parameter of the macro must be the array itself not the address of the element or element
Exactly, so hi ( &a[1], fp, ARRAYSIZE(&a[1])) and hi (&a[1], fp, ARRAYSIZE(a)) are both incorrect. You can make your answer more complete by explaining this since the original question is about the difference between &a[0] and &a[1].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.