Hi all,

I'm working my through Zed Shaw's "Learn C the Hard Way" online book, currently at exercise 17 (link for those interested).

Anyway, I've been scratching my head over the problem of allocating memory for a series of nested structs which contain dynamically sized members. To clarify, I have the following two structs:
Code:
struct Address {
int id;
int set;
char *name;
char *email;
};
Code:
struct Database {
int numrows; int stringsize;
struct Address *rows;
};
The user will be required to enter values for the number of row entries and string size, where each row corresponds to an "Address" struct and string size indicates the size of the name and email fields of each Address struct.

I've come up with the following function for allocating memory in a dynamic fashion. Note that "die" is a function utilising the errno functions to print and exit if something goes wrong.

Code:
struct Connection *Database_open(const char *filename, char mode, int numrows, int stringsize)
{
    struct Connection *conn = malloc(sizeof(struct Connection));
    if(!conn) die("Memory error");


    conn->db = malloc(sizeof(struct Database));
    if(!conn->db) die("Memory error");


    //Allocate memory for a set of row pointers
    conn->db->rows = malloc(sizeof(struct Address*)*numrows);
    if(!conn->db->rows) die("Memory error in row creation");


    //Allocate the memory for each string field of the each Address struct and
    //assign.
    int i = 0;
    for(i = 0; i < numrows; i++){
        conn->db->rows[i].name = (char*)malloc(sizeof(char)*stringsize);
        if(!conn->db->rows[i].name) die("Memory error in name field creation");
        conn->db->rows[i].email = (char*)malloc(sizeof(char)*stringsize);
        if(!conn->db->rows[i].email) die("Memory error in email field creation");
    }  


    ... //irrelevant code


    return conn;
}
It compiles, but it feels wrong. Can anyone suggest a simpler method of allocating the required space and still allowing the Address structs to be indexed through?

I've been wrestling with this for a couple of days it feels like I'm missing something simple.

Your help is much appreciated.