我正在尝试使用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
指向一个Database实例,max_rows
是传递给函数的整数。我还改变了Database结构体的定义:
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)
,我推测这意味着它试图读取一些无法读取的内容。
&
和->
之间的运算符优先级感到模糊,所以当有疑问时,请用括号括起来。为了确保,你尝试过struct Address *addr = &(conn->db->rows[id]);
吗? - Dan Fid
是什么?你确定它在0和max_rows
之间吗? - Dan Fconn
的定义,而不是conn
的类型,虽然这也有帮助。只是我注意到你在一个地方使用了conn->db->rows
,而在另一个地方使用了&conn->db->rows
。这两个conn
是相同的吗?如果你在使用&conn
的conn
已经是一个指针,那么这可能解释了错误。 - Eric Finn