fread()由于某种未知原因而失败

时间:2013-02-03 18:22:29

标签: c file-io fread

编辑:当我更改工作目录时它可以工作,因此文件是在不同的目录中创建的。我之前使用的目录唯一奇怪的是它是一个与VirtualBox一起使用的共享目录。这一直是VirtualBox的错误吗?我最好开始使用一个单独的目录。

我有一个非常奇怪的问题。在我的程序的某个地方,我有这个代码。我修改了它以打印出一些信息来证明问题:

uint8_t section[9];
long pos = ftell(rd);
fseek(rd, 0, SEEK_END);
printf("%li\n",ftell(rd));
fseek(rd, pos, SEEK_SET);
printf("%li\n",ftell(rd));
clearerr(rd);
int i = fread(section, 1, 9, rd);
if (i != 9){
    printf("%i - %i - %i\n",i,feof(rd),ferror(rd));

输出是这样的:

23
14
0 - 0 - 1

因此此时文件的长度为23,光标位于14.我想要9个字节,但fread给出零并显示错误。我在Linux Mint上遇到此问题而在OSX上没有。其他人在debian上似乎没有这个问题。我不知道是什么原因导致了这个问题。有没有办法进一步诊断错误的原因? ferror()给出零信息。

使用“wb +”模式打开文件。

编辑:

我在valgrind中发现了这个模糊的错误:

==22141== Syscall param write(buf) points to uninitialised byte(s)
==22141==    at 0x5B68900: __write_nocancel (syscall-template.S:82)
==22141==    by 0x5AFB882: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1289)
==22141==    by 0x5AFB749: new_do_write (fileops.c:543)
==22141==    by 0x5AFCEB4: _IO_do_write@@GLIBC_2.2.5 (fileops.c:516)
==22141==    by 0x5AFDD3E: _IO_switch_to_get_mode (genops.c:189)
==22141==    by 0x5AFBA96: _IO_file_seekoff@@GLIBC_2.2.5 (fileops.c:999)
==22141==    by 0x5AF4F25: rewind (rewind.c:37)
==22141==    by 0x567D149: CBFileAppend (CBFileEC.c:69)
==22141==    by 0x5473AFA: CBDatabaseCreateDeletionIndex (CBDatabase.c:270)
==22141==    by 0x5473195: CBInitDatabase (CBDatabase.c:112)
==22141==    by 0x54721A1: CBNewAddressStorage (CBAddressStorage.c:37)
==22141==    by 0x401F67: main (testCBAddressManager.c:226)
==22141==  Address 0x402a009 is not stack'd, malloc'd or (recently) free'd
==22141==  Uninitialised value was created by a stack allocation
==22141==    at 0x546F750: ??? (in /media/sf_BitEagle_Projects/cbitcoin/bin/libcbitcoin-storage.2.0.so)

我不知道在哪里???显然,所以我没有运气进一步调试。这很奇怪,因为它在倒带时抱怨()。

感谢。

2 个答案:

答案 0 :(得分:2)

“wb +”根据文档http://en.cppreference.com/w/c/io/fopen销毁现有文件的内容。当您尝试使用“rb +”时,必须首先重新创建该文件,否则您将遇到同样的问题,就好像您使用“wb +”为该调用打开它一样。

编辑:这是您的完整示例代码的样子吗?

int main()
{
  typedef unsigned char uint8_t;

  FILE * rd = fopen("foo.tmp", "wb+");
  uint8_t section[9] = {0};
  long pos = 0;

  fprintf(rd, "01234567890123456789012");

  fseek(rd, 14, SEEK_SET);
  pos = ftell(rd);
  fseek(rd, 0, SEEK_END);
  printf("%li\n",ftell(rd));
  fseek(rd, pos, SEEK_SET);
  printf("%li\n",ftell(rd));
  clearerr(rd);
  int i = fread(section, 1, 9, rd);
  if (i != 9){
    printf("%i - %i - %i\n",i,feof(rd),ferror(rd));
  }

  return 0;
}

答案 1 :(得分:0)

您可能不会相信这一点,但VirtualBox和共享目录确实存在问题。构建过程在普通目录上正常工作。感谢所有试图提供帮助的人。我之前没有使用strace,但我会记住那个!而且我确实得到了最后的工作,这可能会在某一天发挥作用。