所以我目前正在Learn C the Hard Way和粘貼在課外鍛鍊17「fread'ing一個動態分配的結構
只需要什麼是固定大小的數據庫從http://c.learncodethehardway.org/book/ex17.html轉換爲動態調整一個,你取用戶允許的行數和最大字符串長度。
我設法讓程序創建數據庫並將其寫入文件,但我無法弄清楚如何從文件再次讀取程序。
該程序正在編譯,但只要我嘗試執行除創建數據庫之外的任何操作,它都會進行分段轉換。我使用valgrind進行了檢查,直接的原因似乎是從非分配的內存中讀取。我相信這個問題在下面的Database_load函數中。
請注意,這是我第一次發佈一個問題,道歉,如果我張貼太多。
加載起來:
struct Connection *Database_open(const char *filename, char mode)
{
struct Connection *conn = malloc(sizeof(struct Connection));
if(!conn) die("Memory error", conn);
conn->db = malloc(sizeof(struct Database));
if(!conn->db) die("Memory error", conn);
// If we're creating, write a new file otherwise load it up.
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", conn);
return conn;
}
void Database_load(struct Connection *conn)
{
int rc = fread(conn->db, sizeof(struct Database), 1, conn->file);
if(rc != 1) die("Failed to load database.", conn);
const int MAX_ROWS = conn->db->MAX_ROWS;
const int MAX_DATA = conn->db->MAX_DATA;
int i = 0;
// I want to allocate memory for the rows and the strings here...
// Clearly the freads are failing, how would I actually allocate properly?
for(i = 0; i < MAX_ROWS; i++) {
rc = fread(conn->db->rows, sizeof(struct Address),
1 , conn->file);
if(rc != 1) die("Failed to load rows.", conn);
rc = fread(&conn->db->rows[i], sizeof(char),
MAX_DATA, conn->file);
if(rc != MAX_DATA) die("Failed to load characters.", conn);
}
補充說明如下:
涉及的結構:
struct Address {
int id;
int set;
char *name;
char *email;
};
struct Database {
int MAX_DATA;
int MAX_ROWS;
struct Address *rows;
};
struct Connection {
FILE *file;
struct Database *db;
};
創建數據庫:
void Database_create(struct Connection *conn, const int MAX_ROWS, const int MAX_DATA)
{
int i = 0;
conn->db->MAX_ROWS = MAX_ROWS;
conn->db->MAX_DATA = MAX_DATA;
conn->db->rows = (struct Address *)malloc(sizeof(struct Address)*MAX_ROWS);
for(i = 0; i < MAX_ROWS; i++) {
struct Address addr;
addr.id = i;
addr.set = 0;
addr.name = (char *)malloc(sizeof(char)*MAX_DATA);
addr.email = (char *) malloc(sizeof(char)*MAX_DATA);
conn->db->rows[i] = addr;
}
}
最後,清理:
void Database_close(struct Connection *conn)
{
int i = 0;
struct Address *cur_row = NULL;
if(conn) {
if(conn->file) fclose(conn->file);
if(conn->db) {
if(conn->db->rows) {
for(i = 0; i < conn->db->MAX_ROWS; i++) {
cur_row = &conn->db->rows[i];
if(cur_row) {
free(cur_row->name);
free(cur_row->email);
}
}
free(conn->db->rows);
}
free(conn->db);
}
free(conn);
}
}
哦!我實際上並沒有對conn-> db之外的任何東西進行fwrite()。有時間解決這個問題,看看它能做些什麼。 –
一旦我得到了fwrite的工作,並重寫了我所有的函數(malloc需要一個新的地址結構),一切都奏效了。謝謝您的幫助。 –
@MicaiahChang:非常歡迎。 – jxh