malloc(sizeof(struct xxxx))是';不分配任何内存
我正在使用在线书籍练习17学习C,我遇到了一个令人困惑的错误。在本练习中,我被告知使用malloc(sizeof(struct xxxx))为连接和数据库分配内存,如下所示:malloc(sizeof(struct xxxx))是';不分配任何内存,c,memory-management,struct,C,Memory Management,Struct,我正在使用在线书籍练习17学习C,我遇到了一个令人困惑的错误。在本练习中,我被告知使用malloc(sizeof(struct xxxx))为连接和数据库分配内存,如下所示: struct Connection *conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory error"); conn->db = malloc(sizeof(struct Database)); if(!conn->db) die("
struct Connection *conn = malloc(sizeof(struct Connection));
if(!conn) die("Memory error");
conn->db = malloc(sizeof(struct Database));
if(!conn->db) die("Memory error");
当我运行程序时,我得到一个分段错误,然后在valgrind下运行后,我得到以下错误:
==5770== Command: ./ex17 db.dat c
==5770==
==5770== Invalid read of size 1
==5770== at 0x40C4130: _IO_file_fopen@@GLIBC_2.1 (fileops.c:267)
==5770== by 0x40B88CA: __fopen_internal (iofopen.c:90)
==5770== by 0x40B893A: fopen@@GLIBC_2.1 (iofopen.c:103)
==5770== by 0x8048861: Database_open (ex17.c:58)
==5770== by 0x8048C4C: main (ex17.c:156)
==5770== Address 0x77 is not stack'd, malloc'd or (recently) free'd
main中的第156行只是通过函数struct connection*conn=Database\u open(文件名,操作)创建一个新的连接结构代码>,这似乎不是问题所在。在数据库_open的第58行之后是conn->file=fopen(文件名“w”)代码>从错误的not stack'd,malloc'd部分,我假设上面的malloc是问题所在。有人能确认/帮我解决这个问题吗
你的问题是你的fopen
呼叫。模式
应该是字符串,而不是字符
。将模式更改为“r+”
或“w”
另外,在编译时启用更多警告。考虑到如果malloc
s失败,程序会死并显示错误消息,可以肯定地说这段代码不是问题所在。fopen
的第二个参数应该是双引号中的字符串,而不是字符常量:fopen(文件名,“w”)
@MicroVirus是正确的:malloc
调用不是问题。回溯表示您正试图使用值0x77
作为地址0x77
恰好是字符'w'
的ASCII值;这听起来有什么意义吗?请更新您的问题,以包含足够的代码来诊断问题;如果有必要的话,把你的程序缩小到一个小得足以让文章仍然显示问题的地方。换句话说:你的问题是一个简单的打字错误,因此偏离了主题。将来,您可能希望将粘贴代码从练习复制到另一个文件中,并在键入的版本和复制粘贴的版本之间运行diff。@FlorinStingaciu,该链接显示键入错误:)您是从SEGFULT转储中的地址0x77
(带0x77='w'
)计算出来的吗?很好@barakmanos:不,我通过查看堆栈跟踪找到了答案。调用fopen
时程序崩溃fopen
是这样一个核心功能,我知道它可能没有bug。所以我想如果它在fopen
中崩溃了,但是fopen
没有bug,那么传递给它的参数可能是错误的。我原以为filename
可能是罪魁祸首,但在阅读了代码之后,它看起来没有什么可疑之处。只有另外一个参数被传递给fopen
,所以我看了看,意识到它是一个字符而不是字符串,然后想“嗯……我想fopen
接受字符串,而不是字符”。@barakmanos:(继续)谷歌快速搜索和简介显示,是的,它应该是一个字符串,而不是一个字符。(我只是想与大家分享我是如何发现这个问题的,希望它能帮助你在将来进行调试)那么,你最好在你的答案中加入这个概念。函数fopen
需要一个以null结尾的字符串的地址作为第二个参数,OP用'w'
(等于0x77)而不是“w”
调用它。顺便说一句,遇到这个问题的不是我,我只是表达了我的印象,即你能够从堆栈跟踪中检测到'w'
问题,而不需要实际的错误代码(假设你确实检测到了这个问题)。@Cornstalks:我希望有一天能有这样的调试能力