19

I want to write a array containing 16bit integers as raw binary to a file and have tried with the following example:

#  define __int8_t_defined
__intN_t (8, __QI__);
__intN_t (16, __HI__);
__intN_t (32, __SI__);
__intN_t (64, __DI__);

int main(int argc, char *argv[])
{
    FILE * rawf;
    rawf = fopen("./rawPcm","wb");
    int16_t buff[] = {0,0,0};
    fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);
    fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);  
    fclose(rawf);
}

However, the output contains more than just zeros.

$ hexdump -v rawPcm 
0000000 0000 0000 0000 85fd 0804 0001 0000 0000
0000010 0000 85fd 0804 0001                    
0000018

It writes 0000 0000 0000 85fd 0804 0001 for every fwrite(buff,sizeof(int16_t), sizeof(buff),rawf); while I would expect to get only 0000 0000 0000.

What does the additional data represent 85fd 0804 0001 and how do I prevent it from occurring?

TheMeaningfulEngineer
  • 15,679
  • 27
  • 85
  • 143

2 Answers2

19

What does the additional data represent 85fd 0804 0001

Possibly some random garbage data.

how do I prevent it from occurring?

fwrite(buff,sizeof(int16_t), sizeof(buff),rawf); should be written as:

fwrite(buff,sizeof(int16_t), sizeof(buff) / sizeof(buff[0]),rawf);
/*               ^                          ^^^^^^^^^^^^^^^      */
/*       size of each object      Count of objects               */
/*              (2)                  (3)                         */

/* or */
fwrite(buff, sizeof buf[0], sizeof buff / sizeof buff[0], rawf);

sizeof buff / sizeof buff[0] gets the array length in number of objects (or members) while sizeof buff gives the size of array in bytes.

So you are reading past the buff and writing it to the file and invoking undefined behaviour. In your case you are seeing the random garbage data being written to output file.

In your case, sizeof of each element in buff is 2 bytes and buff array has 3 members causing total size to be 6 bytes. When you write fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);, 6 objects of 2 byte each are written to the file which is not something that you want to do.

Now you are writing 6 data of type (size) int16_t starting from buff[0] i.e. buff[0..5] to the output. buff[0..2] are 0s as expected and buff[3..5] are garbage.

Community
  • 1
  • 1
Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
9

The third argument of fwrite is the number of elements of size specified by the second parameter. It is not the total size in bytes, which you are currently doing.

So you are overrunning your buffer.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483