Since the code you presented is not complete, I made a new, simple program. It's a little bit different from the code you provided, particularly in naming. But I hope it could help you anyway.
I should mention that I am not sure what you mean by "disjoint dynamic memory allocation". Also, I am not sure about the term "BIN file", whether it means a "binary file", the .bin
file name extension or some other thing. You may want to adjust my solution to your needs in this regard. Or, if you wish, provide more detail in the comments, and I'll try to adjust my solution accordingly.
As you see, when it comes to memory management, I'm not freeing memory in the code. Instead, I put only comments in the places where you might need to do it. This is only because I think additional code would clutter the existing code too much to be understandable. In a usual project, you may want to set another rules when it comes to freeing memory. Particularly, you may read:
#include <stdlib.h>
#include <stdio.h>
struct auto_t {
int data;
};
struct auto_t * make_node (void) {
return calloc(1, sizeof (struct auto_t));
}
int main (int argc, char * argv[]) {
if (argc != 2) {
// If there are no or more than 1 arguments to the program
return EXIT_FAILURE;
}
// ALLOCATING MEMORY AND INITIALIZING
int auto_inventory_size = 100;
struct auto_t ** auto_inventory = calloc(auto_inventory_size, sizeof (struct auto_t *));
if (auto_inventory == NULL) {
// If calloc failed
return EXIT_FAILURE;
}
struct auto_t ** auto_inventory_read = calloc(auto_inventory_size, sizeof (struct auto_t *));
if (auto_inventory_read == NULL) {
// If calloc failed
// Here you may want to free memory
return EXIT_FAILURE;
}
for (int k = 0; k < auto_inventory_size; ++k) {
auto_inventory[k] = make_node();
if (auto_inventory[k] == NULL) {
// If calloc in make_node failed
// Here you may want to free memory (both the
// whole memory for auto_inventory, and the
// memory for auto_inventory_read allocated
// so far
return EXIT_FAILURE;
}
auto_inventory[k]->data = k;
auto_inventory_read[k] = make_node();
if (auto_inventory_read[k] == NULL) {
// If calloc in make_node failed
// Here you may want to free memory (both the
// whole memory for auto_inventory, and the
// memory for auto_inventory_read allocated
// so far
return EXIT_FAILURE;
}
}
// WRITING TO A FILE
// Open
// Note the mode string is "a". If you need, you can
// use the "ab", "w" or "wb" mode strings (see man 3
// fopen). Because of "a", you need to remove the
// created file if you would like to run the program
// the second time or more, otherwise results will be
// not as expected
FILE * f = fopen(argv[1], "a");
if (f == NULL) {
// If fopen failed
// Here you may want to free memory
return EXIT_FAILURE;
}
// Write
for (int k = 0; k < auto_inventory_size; ++k) {
// Depending on your needs, you may want to check
// the return value of fwrite. Here I decided
// to omit it
fwrite(auto_inventory[k], sizeof (struct auto_t), 1, f);
}
// Close
if (fclose(f) != 0) {
// If fclose failed
// Here you may want to free memory
return EXIT_FAILURE;
}
// READING FROM A FILE
// Open
// Note the mode string is "r". If you need, you can
// use the "rb" mode string (see man 3 fopen)
f = fopen(argv[1], "r");
if (f == NULL) {
// If fopen failed
// Here you may want to free memory
return EXIT_FAILURE;
}
// Read
for (int k = 0; k < auto_inventory_size; ++k) {
// Depending on your needs, you may want to check
// the return value of fread. Here I decided
// to omit it
fread(auto_inventory_read[k], sizeof (struct auto_t), 1, f);
}
// Close
if (fclose(f) != 0) {
// If fclose failed
// Here you may want to free memory
return EXIT_FAILURE;
}
// Verify that reading from file went OK
for (int k = 0; k < auto_inventory_size; ++k) {
printf("[DEBUG] auto_inventory[k]->data == %d\n", auto_inventory[k]->data);
printf("[DEBUG] auto_inventory_read[k]->data == %d\n", auto_inventory_read[k]->data);
printf("\n");
}
// Here you may want to free memory
return EXIT_SUCCESS;
}