【问题标题】:malloc(sizeof(struct xxxx)) isn't allocating any memory [closed]malloc(sizeof(struct xxxx)) 没有分配任何内存[关闭]
【发布时间】:2014-07-03 14:56:47
【问题描述】:

我在练习 17 中使用 Learn C the Hard Way 在线书籍学习 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("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_open(filename, action); 创建一个新的连接结构,这似乎不是问题。一直到 Database_open 中的第 58 行是 conn->file = fopen(filename, 'w'); 从错误的未堆叠、malloc 部分,我认为上面的 malloc 是问题所在。有人可以确认/帮我解决这个问题吗?

Full code

【问题讨论】:

  • 考虑到如果mallocs 失败,程序应该死掉并显示错误消息,可以肯定地说这段代码不是问题。
  • fopen 的第二个参数应该是双引号中的字符串,而不是字符常量:fopen(filename, "w")
  • @MicroVirus 是正确的:malloc 调用不是问题。回溯表明您正在尝试使用值 0x77 作为地址。 0x77恰好是字符'w'的ASCII值;这会响铃吗?请更新您的问题以包含足够的代码来诊断问题;如有必要,请将您的程序缩小到足以发布但仍然存在问题的内容。
  • 换句话说:您的问题是一个简单的错字,因此偏离主题。将来,您可能希望将练习中的代码复制粘贴到另一个文件中,并在您输入的版本和复制粘贴的版本之间运行差异。
  • @FlorinStingaciu 该链接显示错字:)

标签: c memory-management struct


【解决方案1】:

您的问题是您的fopen 电话。 mode 应该是一个字符串,而不是 char。将模式更改为"r+""w"

另外,编译时启用更多警告。

【讨论】:

  • 您从段错误转储中的Address 0x77(带有0x77 == 'w')中发现了这一点?不错!
  • @barakmanos:不,我是通过查看堆栈跟踪发现的。调用fopen 时程序崩溃。 fopen 是一个核心功能,但我知道它可能不是错误的。所以我想如果它在fopen 中崩溃,但fopen 不是错误的,那么可能传递给它的参数是错误的。我认为filename 可能是罪魁祸首,但在阅读代码后,它看起来并不可疑。只有一个其他参数被传递给fopen,所以我看了看,意识到它是一个字符而不是字符串,然后想“嗯……我以为fopen 接受的是字符串,而不是字符”。跨度>
  • @barakmanos:(续)快速的谷歌搜索和简短的manual scan 表明是的,它应该是一个字符串,而不是一个字符。 (我只是想分享一下我是如何发现这个问题的,希望对你以后的调试有所帮助)
  • 好吧,那么您不妨将这个概念添加到您的答案中。函数fopen 需要一个以空字符结尾的字符串的地址作为第二个参数,并且OP 使用'w'(等于0x77)而不是"w" 调用它。顺便说一句,不是我遇到了这个问题,我只是表达了我对您能够从堆栈跟踪中检测到'w' 问题的印象,而您面前没有实际的错误代码(假设您确实有检测到该问题)。
  • @Cornstalks:希望有一天能拥有这样的调试能力
猜你喜欢
  • 2015-02-11
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
相关资源
最近更新 更多