【发布时间】:2012-06-22 13:03:08
【问题描述】:
我正在尝试使用 http://c.learncodethehardway.org/ 学习 C,但我被第 18 章中的一个额外的学分问题困住了 (http://c.learncodethehardway.org/book/learn-c-the-hard- waych18.html) 我希望有人能帮助我。
我遇到的具体问题是有几个这样定义的结构:
#define MAX_ROWS = 500;
#define MAX_DATA = 512;
struct Address {
int id;
int set;
char name[MAX_DATA];
char email[MAX_DATA];
};
struct Database {
struct Address rows[MAX_ROWS];
};
struct Connection {
FILE *file;
struct Database *db;
};
挑战在于重新设计,使rows 可以具有不依赖于该常量的可变大小。
所以在我的 Database_create 方法中,我尝试使用以下内容初始化 rows:
conn->db->rows = (struct Address*) malloc(max_rows * sizeof(struct Address));
其中conn->db 指向数据库实例,max_rows 是传递给函数的 int。
我还将数据库结构更改为
struct Database{
struct Address* rows;
}
那段代码似乎运行正常,但如果我尝试访问 rows 的任何成员,我会遇到分段错误,我认为这意味着我正在尝试访问未使用的内存位。
我在这方面花了好几个小时,我相信我不会离得太远,但我非常感谢任何能让我走上正轨的指导。
编辑:只是想在使用 Valgrind 运行它之后添加更多细节,这会引发错误:
==11972== Invalid read of size 4
==11972== at 0x100001578: Database_set (ex18.c:107)
==11972== by 0x100001A2F: main (ex18.c:175)
==11972== Address 0x7febac00140c is not stack'd, malloc'd or (recently) free'd
它指向的代码行是:
struct Address *addr = &conn->db->rows[id];
if(addr->set) die("Already set, delete it first");
第 107 行是 if(addr->set),我认为这意味着它正在尝试读取它无法读取的内容
【问题讨论】:
-
如果您使用符合 c99 的编译器,它们确实允许可变长度数组。
-
作为一个小问题,您不想强制转换 malloc 的返回值(请参阅:stackoverflow.com/questions/1565496/…)。
-
我对
&和->之间的运算符优先级总是很模糊,所以当有疑问时,用括号括起来。只是为了确定,你试过struct Address *addr = &(conn->db->rows[id]);吗? -
@Scroog1 阅读该问题的已接受答案,看起来您只是不想在不包含 stdlib.h 的情况下使用 malloc。
-
struct Address *addr = &conn->db->rows[id];可以看看conn的定义吗?