Reputation: 372
My question is a simple one...I have the following structs declared:
struct Address {
int id;
int set;
char *name;
char *email;
};
struct Database {
struct Address rows[512];
};
struct Connection {
FILE *file;
struct Database *db;
};
Now having that clear, I initialize my "Database" inside my "Connection" with some dummy Addresses. I later take this database and save it into the file inside my "Connection" struct with:
void Database_write(struct Connection *conn){
rewind(conn->file);
int rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
if(rc != 1){
die("Failed to write database.\n",conn);
}
rc = fflush(conn->file);
if(rc == -1){
die("Cannot flush database.\n",conn);
}
Everything works great when I have a predetermined number of rows inside my "Database" struct for my Addresses i.e. 512. But, what if I want to make the number of rows dynamically? As in maybe as a param passed to a function? I have tried using the following...
struct Database {
struct Address *rows;
};
And allocating space to this pointer with:
conn->db->rows = (struct Address*) malloc(sizeof(struct Address)*max_rows);
With max_rows being a param passed to a function...But, now the problem is that when I go and try to save this to the file inside my "Connection" struct I just save the pointer "struct Address *rows;" and not the data with the space allocated to it. Any suggestions as to how to save this allocated space or have a predetermined array inside a struct and then grow it dynamically?
Thanks in advance!
Upvotes: 1
Views: 1265
Reputation: 101
You are on the right track with malloc for creating a dynamic number of Addresses.
conn->db->rows = (struct Address*) malloc(sizeof(struct Address)*max_rows);
But then you have a problem writing them out to file in Database_write. This is because the dynamically-allocated structure no longer has the number of rows hardwired into it. You will have to change Database_write to
You had:
void Database_write(struct Connection *conn)
{
rewind(conn->file);
int rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
if(rc != 1){
die("Failed to write database.\n",conn);
}
...
You now need something like:
void Database_write(struct Connection *conn, int num_rows)
{
rewind(conn->file);
int rc = fwrite(conn->db, sizeof(struct Database), num_rows, conn->file);
if(rc != num_rows)
{
die("Failed to write database.\n",conn);
}
...
You could also add the number of rows to your database struct to record how many rows are supposed to be in the file:
struct Database
{
int num_rows;
struct Address *rows;
};
In which case you should fwrite the number of rows to file first, then write num_rows of struct Address.
You might also want to look up realloc for changing the number of rows on the fly. Hint - use with care, and pay close attention to the return value.
Upvotes: 3