1

I am currently programming an application for smartphones using C++ and the NDK. For reading external files, I use fread. This works well on Windows, however, on Android phones, I got a mess with my implementation of the deflate decompressor. Of course I thought, there something wrong with my implementation of deflate, but it didn't really make sense as everything worked perfectly on Windows machines. After hours, I was finally able to track down the problem to fread.

I am reading a file of size 4790954 and the return value of fread is also 4790954. I, however discovered, that the buffer starts to contain trash at offset: 4194304. Exactly 4MB. Is there any known limitation on blocksize to be read at once that are defined in ANSI C I am not aware of?? Also, isn't that considered a bug, if the Google NDK fread function returns an amount of read bytes of 4790954, if it however, only read 4194304 bytes (4MB)?

Jongware
  • 22,200
  • 8
  • 54
  • 100
Silverdust
  • 1,503
  • 14
  • 26
  • 1
    Suspect #1, ANSI C, does not contain that limitation, as it uses `size_t` throughout. – Jongware Sep 14 '14 at 13:51
  • 1
    There is no such limitation in C. Are you absolutely positive that the "trash" was written there by `fread()`? Unrelated memory corruption bugs can trash arbitrary portions of memory. It is not impossible that a basic function such as `fread()` is buggy on Android, but it is not very likely either, and such assertion should be accompanied by carefully collected evidence. – user4815162342 Sep 14 '14 at 14:02
  • Its not my intention to assert anything bad related to the sacred google fread function. ;-) I was trying to make sure I didn't overlook something obvious before I dig deeper into the rabbit hole ;-) – Silverdust Sep 14 '14 at 14:19
  • 1
    Can you show your `fread` call? – mafso Sep 14 '14 at 14:23

2 Answers2

0

Is there a limitation on blocksize for reading when using fread in C?

Not per se. The limitation is implied based on the data types. Android is 32-bit only, so size_t is 32-bits. There's also a potential for wrap leading to a smaller read size because of object_size * number_of_objects (these are unsigned values, so they wrap rather than overflow).

From The Open Group Base Specifications Issue 6 and fread:

size_t fread(void *restrict ptr, size_t size, size_t nitems,
       FILE *restrict stream);

And the description:

The fread() function shall read into the array pointed to by ptr up to nitems elements whose size is specified by size in bytes, from the stream pointed to by stream. For each object, size calls shall be made to the fgetc() function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object.

What does ferror(fp) return after the read? Is there an error?

Related: you might want to have a quick look at the answer of Using fread properly. I'm not claiming there's a problem in your usage fo fread or fgetc. But there's no code, so we can't tell.

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
0

I know its quite some time ago but looking around my profile I realized that this question remained open even though I found a solution to the problem a long time aog. The error was rather stupid - I didn't open the file in binary mode using fopen, which led to this strange behaviour...

Silverdust
  • 1,503
  • 14
  • 26