Fwrite a dynamic structure passed by reference












-1















Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:



void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);

while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;

if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;

fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}


And that is how I call this function from main:



FILE* db = NULL;
int choice = 0;
db = openDatabase(db);

Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}


Memory allocation to the structure happens in a different function.



If structure was local, in fwrite as 1st parameter I would write



&carPtr[number-1]


But in my case this does not work.



Car declaration:



struct car
{
char make[15];
char model[15];
int year;
double price;
};









share|improve this question

























  • How is Car declared?

    – Kamil Cuk
    Nov 25 '18 at 20:53






  • 1





    Edited my question to include it

    – Arkadijus
    Nov 25 '18 at 20:57











  • I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in loadData() only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr and use use it to pint to the data.

    – Frankie_C
    Nov 25 '18 at 21:04













  • I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.

    – Arkadijus
    Nov 25 '18 at 21:20











  • To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..

    – too honest for this site
    Nov 25 '18 at 21:22
















-1















Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:



void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);

while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;

if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;

fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}


And that is how I call this function from main:



FILE* db = NULL;
int choice = 0;
db = openDatabase(db);

Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}


Memory allocation to the structure happens in a different function.



If structure was local, in fwrite as 1st parameter I would write



&carPtr[number-1]


But in my case this does not work.



Car declaration:



struct car
{
char make[15];
char model[15];
int year;
double price;
};









share|improve this question

























  • How is Car declared?

    – Kamil Cuk
    Nov 25 '18 at 20:53






  • 1





    Edited my question to include it

    – Arkadijus
    Nov 25 '18 at 20:57











  • I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in loadData() only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr and use use it to pint to the data.

    – Frankie_C
    Nov 25 '18 at 21:04













  • I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.

    – Arkadijus
    Nov 25 '18 at 21:20











  • To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..

    – too honest for this site
    Nov 25 '18 at 21:22














-1












-1








-1








Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:



void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);

while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;

if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;

fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}


And that is how I call this function from main:



FILE* db = NULL;
int choice = 0;
db = openDatabase(db);

Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}


Memory allocation to the structure happens in a different function.



If structure was local, in fwrite as 1st parameter I would write



&carPtr[number-1]


But in my case this does not work.



Car declaration:



struct car
{
char make[15];
char model[15];
int year;
double price;
};









share|improve this question
















Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:



void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);

while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;

if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;

fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}


And that is how I call this function from main:



FILE* db = NULL;
int choice = 0;
db = openDatabase(db);

Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}


Memory allocation to the structure happens in a different function.



If structure was local, in fwrite as 1st parameter I would write



&carPtr[number-1]


But in my case this does not work.



Car declaration:



struct car
{
char make[15];
char model[15];
int year;
double price;
};






c






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 25 '18 at 20:55







Arkadijus

















asked Nov 25 '18 at 20:47









ArkadijusArkadijus

145




145













  • How is Car declared?

    – Kamil Cuk
    Nov 25 '18 at 20:53






  • 1





    Edited my question to include it

    – Arkadijus
    Nov 25 '18 at 20:57











  • I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in loadData() only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr and use use it to pint to the data.

    – Frankie_C
    Nov 25 '18 at 21:04













  • I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.

    – Arkadijus
    Nov 25 '18 at 21:20











  • To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..

    – too honest for this site
    Nov 25 '18 at 21:22



















  • How is Car declared?

    – Kamil Cuk
    Nov 25 '18 at 20:53






  • 1





    Edited my question to include it

    – Arkadijus
    Nov 25 '18 at 20:57











  • I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in loadData() only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr and use use it to pint to the data.

    – Frankie_C
    Nov 25 '18 at 21:04













  • I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.

    – Arkadijus
    Nov 25 '18 at 21:20











  • To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..

    – too honest for this site
    Nov 25 '18 at 21:22

















How is Car declared?

– Kamil Cuk
Nov 25 '18 at 20:53





How is Car declared?

– Kamil Cuk
Nov 25 '18 at 20:53




1




1





Edited my question to include it

– Arkadijus
Nov 25 '18 at 20:57





Edited my question to include it

– Arkadijus
Nov 25 '18 at 20:57













I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in loadData() only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr and use use it to pint to the data.

– Frankie_C
Nov 25 '18 at 21:04







I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in loadData() only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr and use use it to pint to the data.

– Frankie_C
Nov 25 '18 at 21:04















I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.

– Arkadijus
Nov 25 '18 at 21:20





I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.

– Arkadijus
Nov 25 '18 at 21:20













To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..

– too honest for this site
Nov 25 '18 at 21:22





To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..

– too honest for this site
Nov 25 '18 at 21:22












3 Answers
3






active

oldest

votes


















0














Car *pnt


this is a pointer to Car.



The expression *(...) dereferences the ... into an object.



The expression a[b] is equal to *(a + b).



Car* carPtr


in a function parameter list (ie. in function(... Car *carPtr ....) is equal to:



Car **carPtr


This is a pointer to a pointer to Car.



&carPtr[x]


is equal to:



carPtr + x


which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:



&(*carPtr)[x]


which is equal to:



((*carPtr) + x)


So try:



fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


Also I would rewrite the



(*carPtr+number-1)->


into



(*carPtr)[number - 1].


as to indicate that you are handling a pointer to an array.



But really, I would rewrite the api to handle better abstraction:



struct cars_s {
Car *cars;
size_t carslen;
};

int main() {
struct cars_s cars;

insertData(db, &cars);
...
editData(db, &cars);
}


which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars) and cars->cars[x].year = year instead of Cars *cars, int *size and (*carPtr)[x].year = year.






share|improve this answer


























  • Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.

    – Arkadijus
    Nov 25 '18 at 21:15











  • Do you memset(cars, 0, sizeof(Car)) or call calloc on allocation? If not, there will be random values after the null terminator in string.

    – Kamil Cuk
    Nov 25 '18 at 21:16













  • Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.

    – Arkadijus
    Nov 25 '18 at 21:31













  • Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.

    – Kamil Cuk
    Nov 25 '18 at 21:47



















1














fwrite expects a pointer to a byte buffer to write.



If you have a local variable (including structure), you would need to get its address with the & operator, like this:



Car myCar;
fwrite(&myCar, sizeof(Car), 1, fout);


But, if you already have a pointer, then you don't need the & opertator:



Car *myCar;
fwrite(myCar, sizeof(Car), 1, fout);


Same thing goes if you have an array of pointers to structures:



Car* cars;
fwrite(cars[i], sizeof(Car), 1, fout);


Since cars[i] already has the address fwrite needs, there is no need for any operators.



One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).



So, those 15 char arrays may have an extra byte appended to round to 16.
If you write the whole structure to file, those bytes will also be written.



This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.






share|improve this answer
























  • Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.

    – Arkadijus
    Nov 25 '18 at 21:13













  • How are you looking at the file? Are you using a hex editor? Windows Notepad?

    – Lev M.
    Nov 25 '18 at 22:13











  • Another function freads file to a structure which i print afterwards.

    – Arkadijus
    Nov 25 '18 at 22:26











  • Is it possible the read function is incorrect? Try looking at the file with hex editor.

    – Lev M.
    Nov 26 '18 at 5:34



















0














The problem was not fwrite, but fseek after all.
This:



fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);


must be changed to this:



fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);


I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.



As for correct way to write fwrite:



fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


This works perfectly






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53471806%2ffwrite-a-dynamic-structure-passed-by-reference%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Car *pnt


    this is a pointer to Car.



    The expression *(...) dereferences the ... into an object.



    The expression a[b] is equal to *(a + b).



    Car* carPtr


    in a function parameter list (ie. in function(... Car *carPtr ....) is equal to:



    Car **carPtr


    This is a pointer to a pointer to Car.



    &carPtr[x]


    is equal to:



    carPtr + x


    which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:



    &(*carPtr)[x]


    which is equal to:



    ((*carPtr) + x)


    So try:



    fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


    Also I would rewrite the



    (*carPtr+number-1)->


    into



    (*carPtr)[number - 1].


    as to indicate that you are handling a pointer to an array.



    But really, I would rewrite the api to handle better abstraction:



    struct cars_s {
    Car *cars;
    size_t carslen;
    };

    int main() {
    struct cars_s cars;

    insertData(db, &cars);
    ...
    editData(db, &cars);
    }


    which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars) and cars->cars[x].year = year instead of Cars *cars, int *size and (*carPtr)[x].year = year.






    share|improve this answer


























    • Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.

      – Arkadijus
      Nov 25 '18 at 21:15











    • Do you memset(cars, 0, sizeof(Car)) or call calloc on allocation? If not, there will be random values after the null terminator in string.

      – Kamil Cuk
      Nov 25 '18 at 21:16













    • Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.

      – Arkadijus
      Nov 25 '18 at 21:31













    • Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.

      – Kamil Cuk
      Nov 25 '18 at 21:47
















    0














    Car *pnt


    this is a pointer to Car.



    The expression *(...) dereferences the ... into an object.



    The expression a[b] is equal to *(a + b).



    Car* carPtr


    in a function parameter list (ie. in function(... Car *carPtr ....) is equal to:



    Car **carPtr


    This is a pointer to a pointer to Car.



    &carPtr[x]


    is equal to:



    carPtr + x


    which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:



    &(*carPtr)[x]


    which is equal to:



    ((*carPtr) + x)


    So try:



    fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


    Also I would rewrite the



    (*carPtr+number-1)->


    into



    (*carPtr)[number - 1].


    as to indicate that you are handling a pointer to an array.



    But really, I would rewrite the api to handle better abstraction:



    struct cars_s {
    Car *cars;
    size_t carslen;
    };

    int main() {
    struct cars_s cars;

    insertData(db, &cars);
    ...
    editData(db, &cars);
    }


    which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars) and cars->cars[x].year = year instead of Cars *cars, int *size and (*carPtr)[x].year = year.






    share|improve this answer


























    • Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.

      – Arkadijus
      Nov 25 '18 at 21:15











    • Do you memset(cars, 0, sizeof(Car)) or call calloc on allocation? If not, there will be random values after the null terminator in string.

      – Kamil Cuk
      Nov 25 '18 at 21:16













    • Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.

      – Arkadijus
      Nov 25 '18 at 21:31













    • Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.

      – Kamil Cuk
      Nov 25 '18 at 21:47














    0












    0








    0







    Car *pnt


    this is a pointer to Car.



    The expression *(...) dereferences the ... into an object.



    The expression a[b] is equal to *(a + b).



    Car* carPtr


    in a function parameter list (ie. in function(... Car *carPtr ....) is equal to:



    Car **carPtr


    This is a pointer to a pointer to Car.



    &carPtr[x]


    is equal to:



    carPtr + x


    which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:



    &(*carPtr)[x]


    which is equal to:



    ((*carPtr) + x)


    So try:



    fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


    Also I would rewrite the



    (*carPtr+number-1)->


    into



    (*carPtr)[number - 1].


    as to indicate that you are handling a pointer to an array.



    But really, I would rewrite the api to handle better abstraction:



    struct cars_s {
    Car *cars;
    size_t carslen;
    };

    int main() {
    struct cars_s cars;

    insertData(db, &cars);
    ...
    editData(db, &cars);
    }


    which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars) and cars->cars[x].year = year instead of Cars *cars, int *size and (*carPtr)[x].year = year.






    share|improve this answer















    Car *pnt


    this is a pointer to Car.



    The expression *(...) dereferences the ... into an object.



    The expression a[b] is equal to *(a + b).



    Car* carPtr


    in a function parameter list (ie. in function(... Car *carPtr ....) is equal to:



    Car **carPtr


    This is a pointer to a pointer to Car.



    &carPtr[x]


    is equal to:



    carPtr + x


    which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:



    &(*carPtr)[x]


    which is equal to:



    ((*carPtr) + x)


    So try:



    fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


    Also I would rewrite the



    (*carPtr+number-1)->


    into



    (*carPtr)[number - 1].


    as to indicate that you are handling a pointer to an array.



    But really, I would rewrite the api to handle better abstraction:



    struct cars_s {
    Car *cars;
    size_t carslen;
    };

    int main() {
    struct cars_s cars;

    insertData(db, &cars);
    ...
    editData(db, &cars);
    }


    which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars) and cars->cars[x].year = year instead of Cars *cars, int *size and (*carPtr)[x].year = year.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 25 '18 at 21:06

























    answered Nov 25 '18 at 21:01









    Kamil CukKamil Cuk

    12.2k1529




    12.2k1529













    • Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.

      – Arkadijus
      Nov 25 '18 at 21:15











    • Do you memset(cars, 0, sizeof(Car)) or call calloc on allocation? If not, there will be random values after the null terminator in string.

      – Kamil Cuk
      Nov 25 '18 at 21:16













    • Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.

      – Arkadijus
      Nov 25 '18 at 21:31













    • Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.

      – Kamil Cuk
      Nov 25 '18 at 21:47



















    • Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.

      – Arkadijus
      Nov 25 '18 at 21:15











    • Do you memset(cars, 0, sizeof(Car)) or call calloc on allocation? If not, there will be random values after the null terminator in string.

      – Kamil Cuk
      Nov 25 '18 at 21:16













    • Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.

      – Arkadijus
      Nov 25 '18 at 21:31













    • Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.

      – Kamil Cuk
      Nov 25 '18 at 21:47

















    Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.

    – Arkadijus
    Nov 25 '18 at 21:15





    Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.

    – Arkadijus
    Nov 25 '18 at 21:15













    Do you memset(cars, 0, sizeof(Car)) or call calloc on allocation? If not, there will be random values after the null terminator in string.

    – Kamil Cuk
    Nov 25 '18 at 21:16







    Do you memset(cars, 0, sizeof(Car)) or call calloc on allocation? If not, there will be random values after the null terminator in string.

    – Kamil Cuk
    Nov 25 '18 at 21:16















    Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.

    – Arkadijus
    Nov 25 '18 at 21:31







    Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.

    – Arkadijus
    Nov 25 '18 at 21:31















    Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.

    – Kamil Cuk
    Nov 25 '18 at 21:47





    Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.

    – Kamil Cuk
    Nov 25 '18 at 21:47













    1














    fwrite expects a pointer to a byte buffer to write.



    If you have a local variable (including structure), you would need to get its address with the & operator, like this:



    Car myCar;
    fwrite(&myCar, sizeof(Car), 1, fout);


    But, if you already have a pointer, then you don't need the & opertator:



    Car *myCar;
    fwrite(myCar, sizeof(Car), 1, fout);


    Same thing goes if you have an array of pointers to structures:



    Car* cars;
    fwrite(cars[i], sizeof(Car), 1, fout);


    Since cars[i] already has the address fwrite needs, there is no need for any operators.



    One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).



    So, those 15 char arrays may have an extra byte appended to round to 16.
    If you write the whole structure to file, those bytes will also be written.



    This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.






    share|improve this answer
























    • Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.

      – Arkadijus
      Nov 25 '18 at 21:13













    • How are you looking at the file? Are you using a hex editor? Windows Notepad?

      – Lev M.
      Nov 25 '18 at 22:13











    • Another function freads file to a structure which i print afterwards.

      – Arkadijus
      Nov 25 '18 at 22:26











    • Is it possible the read function is incorrect? Try looking at the file with hex editor.

      – Lev M.
      Nov 26 '18 at 5:34
















    1














    fwrite expects a pointer to a byte buffer to write.



    If you have a local variable (including structure), you would need to get its address with the & operator, like this:



    Car myCar;
    fwrite(&myCar, sizeof(Car), 1, fout);


    But, if you already have a pointer, then you don't need the & opertator:



    Car *myCar;
    fwrite(myCar, sizeof(Car), 1, fout);


    Same thing goes if you have an array of pointers to structures:



    Car* cars;
    fwrite(cars[i], sizeof(Car), 1, fout);


    Since cars[i] already has the address fwrite needs, there is no need for any operators.



    One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).



    So, those 15 char arrays may have an extra byte appended to round to 16.
    If you write the whole structure to file, those bytes will also be written.



    This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.






    share|improve this answer
























    • Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.

      – Arkadijus
      Nov 25 '18 at 21:13













    • How are you looking at the file? Are you using a hex editor? Windows Notepad?

      – Lev M.
      Nov 25 '18 at 22:13











    • Another function freads file to a structure which i print afterwards.

      – Arkadijus
      Nov 25 '18 at 22:26











    • Is it possible the read function is incorrect? Try looking at the file with hex editor.

      – Lev M.
      Nov 26 '18 at 5:34














    1












    1








    1







    fwrite expects a pointer to a byte buffer to write.



    If you have a local variable (including structure), you would need to get its address with the & operator, like this:



    Car myCar;
    fwrite(&myCar, sizeof(Car), 1, fout);


    But, if you already have a pointer, then you don't need the & opertator:



    Car *myCar;
    fwrite(myCar, sizeof(Car), 1, fout);


    Same thing goes if you have an array of pointers to structures:



    Car* cars;
    fwrite(cars[i], sizeof(Car), 1, fout);


    Since cars[i] already has the address fwrite needs, there is no need for any operators.



    One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).



    So, those 15 char arrays may have an extra byte appended to round to 16.
    If you write the whole structure to file, those bytes will also be written.



    This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.






    share|improve this answer













    fwrite expects a pointer to a byte buffer to write.



    If you have a local variable (including structure), you would need to get its address with the & operator, like this:



    Car myCar;
    fwrite(&myCar, sizeof(Car), 1, fout);


    But, if you already have a pointer, then you don't need the & opertator:



    Car *myCar;
    fwrite(myCar, sizeof(Car), 1, fout);


    Same thing goes if you have an array of pointers to structures:



    Car* cars;
    fwrite(cars[i], sizeof(Car), 1, fout);


    Since cars[i] already has the address fwrite needs, there is no need for any operators.



    One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).



    So, those 15 char arrays may have an extra byte appended to round to 16.
    If you write the whole structure to file, those bytes will also be written.



    This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 25 '18 at 20:57









    Lev M.Lev M.

    768314




    768314













    • Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.

      – Arkadijus
      Nov 25 '18 at 21:13













    • How are you looking at the file? Are you using a hex editor? Windows Notepad?

      – Lev M.
      Nov 25 '18 at 22:13











    • Another function freads file to a structure which i print afterwards.

      – Arkadijus
      Nov 25 '18 at 22:26











    • Is it possible the read function is incorrect? Try looking at the file with hex editor.

      – Lev M.
      Nov 26 '18 at 5:34



















    • Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.

      – Arkadijus
      Nov 25 '18 at 21:13













    • How are you looking at the file? Are you using a hex editor? Windows Notepad?

      – Lev M.
      Nov 25 '18 at 22:13











    • Another function freads file to a structure which i print afterwards.

      – Arkadijus
      Nov 25 '18 at 22:26











    • Is it possible the read function is incorrect? Try looking at the file with hex editor.

      – Lev M.
      Nov 26 '18 at 5:34

















    Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.

    – Arkadijus
    Nov 25 '18 at 21:13







    Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.

    – Arkadijus
    Nov 25 '18 at 21:13















    How are you looking at the file? Are you using a hex editor? Windows Notepad?

    – Lev M.
    Nov 25 '18 at 22:13





    How are you looking at the file? Are you using a hex editor? Windows Notepad?

    – Lev M.
    Nov 25 '18 at 22:13













    Another function freads file to a structure which i print afterwards.

    – Arkadijus
    Nov 25 '18 at 22:26





    Another function freads file to a structure which i print afterwards.

    – Arkadijus
    Nov 25 '18 at 22:26













    Is it possible the read function is incorrect? Try looking at the file with hex editor.

    – Lev M.
    Nov 26 '18 at 5:34





    Is it possible the read function is incorrect? Try looking at the file with hex editor.

    – Lev M.
    Nov 26 '18 at 5:34











    0














    The problem was not fwrite, but fseek after all.
    This:



    fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);


    must be changed to this:



    fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);


    I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.



    As for correct way to write fwrite:



    fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


    This works perfectly






    share|improve this answer




























      0














      The problem was not fwrite, but fseek after all.
      This:



      fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);


      must be changed to this:



      fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);


      I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.



      As for correct way to write fwrite:



      fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


      This works perfectly






      share|improve this answer


























        0












        0








        0







        The problem was not fwrite, but fseek after all.
        This:



        fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);


        must be changed to this:



        fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);


        I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.



        As for correct way to write fwrite:



        fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


        This works perfectly






        share|improve this answer













        The problem was not fwrite, but fseek after all.
        This:



        fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);


        must be changed to this:



        fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);


        I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.



        As for correct way to write fwrite:



        fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);


        This works perfectly







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 26 '18 at 13:25









        ArkadijusArkadijus

        145




        145






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53471806%2ffwrite-a-dynamic-structure-passed-by-reference%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Costa Masnaga