【问题标题】:Why does a call to fread set my file pointer to null?为什么调用 fread 会将我的文件指针设置为空?
【发布时间】:2013-05-18 15:14:43
【问题描述】:

我有一个文件指针,在调用 fread 之前有效,之后为 NULL,我真的很想知道为什么。

以下是相关代码:

244 // open the file for reading
245 clo->heap_file = open_file(heap_path, "rb");

443 // allocate memory to read a page from the file
444 file_page = safe_malloc(clo->page_size);

446 // read a page in to memory from the file
447 read_page(file_page, clo);

void *
safe_malloc(size_t size)
{
   void * mem_block = NULL;

   mem_block = calloc(1, size);

   if (mem_block == NULL) {
      fprintf(stderr, "ERROR: safe_malloc() failed to allocate memory.\n");
      exit(EXIT_FAILURE);
   }

   return (mem_block);
}

FILE *
open_file(char * file_name, char * file_mode)
{
    FILE * fp;
    char * err_msg = ((strcmp(file_mode, "rb") == 0)
          ? "File not found"
          : "File could not be created");

    fp = fopen(file_name, file_mode);

    /* Print an appropriate error message and exit if open failed */
    if (fp == NULL) {
       fprintf(stderr, "%s: %s\n", err_msg, file_name);
       exit(EXIT_FAILURE);
    }

    return fp;
}

void
read_page(clo_t * clo, void * file_page)
{
   fread(file_page, sizeof(size_t), clo->page_size, clo->heap_file);

   if (ferror(clo->heap_file)) {
      fprintf(stderr, "ERROR: could not read heap file!\n\n");
      free(file_page);
      destroy_clo(clo);
      exit(EXIT_FAILURE);
   }
}

GDB 跟踪:

(gdb) p clo->heap_file
$1 = (FILE *) 0x603070
(gdb) s
read_page (clo=0x6032d0, file_page=0x603010) at dbquery.c:331
331        fread(file_page, clo->page_size, 1, clo->heap_file);
(gdb) s
333        if (ferror(clo->heap_file)) {
(gdb) p clo->heap_file
$2 = (FILE *) 0x0

而且 Valgrind 也没有表明我做错了什么......

我想我很擅长处理返回值,确保指针有效等,但这个让我很难过。

【问题讨论】:

  • 你确定fread(file_page, sizeof(size_t),...
  • 一行 447 您将参数传递给read_page 的顺序错误
  • 如果 valgrind 没有在这里拾取任何东西,那么 valgrind 有问题。您使用的是哪个操作系统?
  • gdb 输出中显示的clo->heap_file 的地址是什么?

标签: c file-io fread


【解决方案1】:

您有 2 个问题,

  1. 根据函数的定义将447 read_page(file_page, clo); 更改为447 read_page(clo, file_page);

  2. fread(file_page, sizeof(size_t), clo->page_size, clo->heap_file); 更改为fread(file_page, 1, clo->page_size, clo->heap_file);。不要使用sizeof(size_t) 作为fread 的第二个参数。

    您的呼叫将尝试读取sizeof(size_t) * clo->page_size 字节,这比您为file_page 分配的字节数多,即1 * clo->page_size

【讨论】:

  • 事情总是那么简单。我不敢相信我没有看到这一点,但我也不明白为什么编译器没有抱怨 read_page 的参数不匹配。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-09
  • 2011-04-18
  • 2010-10-16
  • 2012-09-15
  • 2012-05-28
  • 1970-01-01
相关资源
最近更新 更多