Search code examples
cfunctionstructbinaryfiles

Why is struct int value not being carried on to the next function?


I'm practising how to work with binary files and playing around with storing, reading and printing out some int values. So, naturally, I've come across a little something that does not affect the functionality of the code (that is, for what I want it to do so far) but it bugs me because I can't seem to find an answer as to why it happens.

I've found, as you'll see in the code below, that if I assign 'cod.x' as a parameter in the function 'create' (right as it is right now), then assign 'cod.y' to the fread in the 'read' function BUT instead I set it to print 'cod.x' in the following line, I end up getting a sequence of 9s. Which makes perfect sense, it was the last int value assigned by the for loop in the former function.

Now, however, if in both functions I swap 'cod.x' for 'cod.y' (that's to say, I order it to print 'cod.y' expecting to see the sequence of 9s again) I get 0s, as I would (correctly, I think, since it's been unused so far) with 'cod.z'.

If in this second go I used 'cod.y' only back in the fuction 'create', why does this happen? Shouldn't the 9s carry through like it did with 'cod.x' before?

What am I missing?

(Funny thing is I found the 9s do carry through if I assign 'cod.z' (instead of 'cod.x') to the fread in the 'read' function. Then, in the next line, I order it to print 'cod.y' and the sequence of 9s is there all right!

So, it sort of seems like a new function writing new data on a variable that 'comes before' the one used by the preceding function ( x is declared "before" y , y "before" z...in a way?) automatically deletes what the the latter variable had stored. I don't know if this is at all a relevant observation but I did point it out.)

 #define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct nums{
    int x, y, z;
}cod;

void create(FILE* BinList);
void read(FILE* BinList);
//void change(FILE* BinList);


int main(void)
{
    FILE * BinList;

    BinList = fopen("handylist.bin", "wb");
    if (!BinList)   return 1;
    create(BinList);  //sequence 0123456789 is written in the bin file

    BinList = fopen("handylist.bin", "rb");
    if (!BinList)   return 1;
    read(BinList);  // sequence is printed in both ascending and descending order

    return 0;

}


void create(FILE* BinList) {

    int i;

    for (i = 0; i < 10; i++)
        { 
            cod.x = i;      
            fwrite(&cod.x, sizeof(struct nums), 1, BinList);  
        }

    printf("Last stored value: %d", cod.x); 

    fclose(BinList);
}



void read(FILE* BinList)
{
    int i;

    printf("\n\nCopied Data:");

    for (i = 0; i < 10; i++)
    {
        fread(&cod.y, sizeof(struct nums), 1, BinList);
        printf("\n%d", cod.y);         //here is where the problem happens

    }

    printf("\n\n\n");
    printf("Values: x:%d, y:%d, z:%d\n",cod.x,cod.y,cod.z);  //checking struct values


    printf("Order is inverted:\n");

    for (i = 9; i >= 0; i--)
    {
        fseek(BinList, sizeof(struct nums) *i, SEEK_SET);
        fread(&cod.z, sizeof(struct nums), 1, BinList);

        printf("%d \n", cod.z);

    }

    fclose(BinList);

}

Solution

  • As to your reply to my hint, I'll provide more details here as a answer.

    fwrite(&cod.x, sizeof(struct nums), 1, BinList);  
    

    Here you write from the address of x in the structure cod a number of bytes. You write the whole struct. There is no problem because &cod and &cod.x are the same because x is the first member of the structure.

    fread(&cod.y, sizeof(struct nums), 1, BinList);
    

    Here you read a number of bytes. You read the size of the whole strucure, that is you read an x, y and z. But you place that starting at cod.y. So you put there bytes for the value of y, of z and of ??? There is no more structure to place bytes! So the last bytes you place "in memory that is not yours."

    cod.x   y   z    ???
    +----+----+----+----....
    |    |    |    |
    +----+----+----+----....
            ^    ^    ^
            |    |    |
        ----+----+----+  read puts the data here