2013-07-17 250 views
0

這是學習C的一個難題。這是用C 數據庫管理系統,我有三個結構: -初始化嵌套結構

struct Address { 
     int id; 
     int set; 
     char *name; 
     char *email; 
}; 

struct Database { 
int rows; 
    struct Address *row; 
}; 

struct Connection { 
    FILE *file; 
    struct Database *db; 
}; 

我試圖初始化數據庫結構。但我越來越segfault

void Database_create(struct Connection *conn, int no_of_rows) 
    { 
     int i = 0; 
    conn->db->row_num = no_of_rows; 

     for(i = 0; i < conn->db->row_num; i++) { 

     // make a prototype to initialize it 
     struct Address addr; 
     addr.id = i; 
     addr.set = 0; 

     // then just assign it 
     conn->db->rows[i] = addr; 
     } 
    } 

我做了另一個功能,分配內存到這些結構。

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

    int number = conn->db->rows; 

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

     conn->db->row = malloc(sizeof(*conn->db->row) * number); 
     if(!conn->db->row) die("Memory error"); 

     if(mode == 'c') { 
     conn->file = fopen(filename, "w"); 
     } else { 
     conn->file = fopen(filename, "r+"); 

     if(conn->file) { 
     Database_load(conn); 
     } 
    } 

    if(!conn->file) die("Failed to open the file"); 

     return conn; 
    } 

的valgrind說,在Database_open「使用大小爲4的初始化值」()

可能有人建議我可能是錯在這裏做什麼?

+0

爲什麼你使用'rows'作爲數組,當它只是一個'int'? – tay10r

+0

使用調試器查看導致段錯誤的原因。最有可能''conn-> db'沒有初始化或者什麼 –

+0

@Ajit你應該包括你如何調用'Database_create' – tay10r

回答

1

db in Connection and row in Database are uninitialised pointers。您需要初始化它們併爲它們指向的結構提供存儲。

你或許可以通過改變Connection節省一些動態分配有它Database作爲成員,而不是一個指針

struct Connection { 
    FILE *file; 
    struct Database db; 
}; 

您需要爲數據庫中的行分配內存

conn->db.row = malloc(no_of_rows * sizeof(*conn->db.row)); 

Database_create會然後看起來像

int Database_create(struct Connection *conn, int no_of_rows) 
{ 
    int i = 0; 
    conn->db.rows = no_of_rows; 
    conn->db.row = malloc(no_of_rows * sizeof(*conn->db.row)); 
    if (conn->db.row == NULL) { 
     /* out of memory */ 
     return 1; /* indicate failure to caller */ 
    } 
    for(i = 0; i < conn->db->rows; i++) { 
     conn->db.row[i].id = i; 
     conn->db.row[i].set = 0; 
    } 
    return 0; /* indicate success to caller */ 
} 

請注意,這假設內存已分配爲Connection

+1

除非我讀錯了,'rows'是一個int而不是一個指針 – tay10r

+0

謝謝,我的意思是'row'('Address *')。現在糾正 – simonc

+0

當然,你可能還想包括他使用行作爲他的代碼中的指針 – tay10r