【问题标题】:can't access a place in memory无法访问内存中的某个位置
【发布时间】:2019-10-27 07:40:19
【问题描述】:

我试图在 C 中读取一个 32 字节的二进制文件,但是当我运行我的程序时,我不断收到“分段错误(代码转储)”, 如果有人可以通过指出我哪里出错来帮助我,那就太好了? 我的代码如下:

int main()
{


   char *binary = "/path/to/myfiles/program1.ijvm";
   FILE *fp;
   char buffer[32];

   // Open read-only
   fp = fopen(binary, "rb");

   // Read 128 bytes into buffer
   fread (buffer, sizeof(char), 32, fp);



   return 0;
 }

【问题讨论】:

  • 检查错误代码的时间,可能 fp 为空(顺便说一句,在编译时激活警告也会指出一些潜在问题...)
  • 你正在读取 32 个字节,而不是 128
  • 请不要在注释中重复代码中写的内容。它导致了我们在这里看到的:带有文字的注释几乎总是错误的。 ;-)
  • 如果这些答案中的任何一个有帮助,请点赞和/或接受它们作为答案。另外,你发现问题了吗?

标签: c file fread


【解决方案1】:

必须检查fopen()的返回结果。

我假设您在 fread() 调用中遇到了段错误,因为您的数据文件不存在或无法打开,并且您正在尝试使用 NULL FILE 结构。

查看以下安全代码:

#include <stdio.h>
#include <stdint.h>

#define SIZE_BUFFER      32

int main()
{
   char *binary = "data.txt";
   FILE *fp = NULL;
   char buffer[SIZE_BUFFER];

   // Open read-only
   fp = fopen(binary, "rb");

   // Read SIZE_BUFFER bytes into buffer
   if( fp )
   {
        printf("Elements read %ld\n", fread (buffer, sizeof(char), SIZE_BUFFER, fp));
        fclose(fp);
   }
   else
   {
        // Use perror() here to show a text description of what failed and why
        perror("Unable to open file: ");
   }
   return 0;
 }

当我执行此代码时,它不会崩溃,如果文件打开,它将打印读取的元素数量,如果文件无法打开,它将打印“无法打开文件”。

如 cmets 中所述,您还应该关闭正在退出的文件。您可以做的另一件事是:

FILE *fp = fopen(.....);

而不是在两个单独的步骤中声明和分配。

【讨论】:

  • 他还应该在返回之前关闭文件
  • 为什么必须将fp初始化为NULLFILE *fp = fopen("/foo/bar/baz.quux"); 之类的呢?
  • @EdwardMinnix 当然,你可以在同一行做 fp 的打开和赋值。
  • fp 不需要初始化。它在使用前稍后设置。还行吧。如果是在被使用之前被使用,那将是一个问题
  • @Chimera - 不用担心 - 它发生在我们最好的人身上
【解决方案2】:

有两个可能的原因

  1. fopen(3) 函数由于某种原因失败,这意味着fp 为NULL,然后您尝试使用fread(3) 中的空指针。这可能会崩溃。 @OznOg 已经给出了一个微妙的暗示来研究这个方向。
  2. 如果fopen 调用成功(即fp 在调用fopen 后为非NULL),代码仍然会崩溃,因为您正在将32 个字符读入变量binary,而binary仅使用 30 个字符进行了初始化。

【讨论】:

  • 但是他声明了char binary[32],而不是binary[30]
  • 缓冲区大小不是问题。这正是正在读取的字节数的大小。最肯定的问题是文件没有打开而 fp 为空。
  • 感谢 EdwardMinnix 和 Chimera 的 cmets。在我发布我的 cmets 后,他编辑了他的代码,因此出现了这种差异或混乱。早些时候,它类似于 'char *buffer = "/path/to/myfiles/program1.ijvm" 这在 gerardo 对这个问题的另一个回答中也提到了
【解决方案3】:

这是因为路径。确保"/path/to/myfiles/program1.ijvm" 指向现有文件。 您应该始终检查fopen 的返回值。

\\Open read-only
fp = fopen(binary, "rb");
if(fp==NULL){
    perror("problem opening the file");
    exit(EXIT_FAILURE);
}

还请注意,您正在读取缓冲区中的 32 个字节,而不是您评论中所说的 128 个字节。

【讨论】:

    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    相关资源
    最近更新 更多