马慧超 马慧超 - 1 year ago 74
C Question

C write uint16 to file got Error

My operation-system is window,I want to write my data to a pcm with 16bit.Here is my code:

typedef unsigned short uint16;
void write2PCM(char* file_path, int length, double* data) {
FILE* file=NULL;
file = fopen(file_path, "wb+");
for (int i = 0; i < length; i++) {
uint16 val=data[i]*10000;
uint16 fin_val = (val >> 8 & 0x00ff) | (val << 8 & 0xff00);
fwrite(fin_val,sizeof(fin_val),1,file);
}

fclose;}


and when I invoke it,I got Error in the place of fwrite:
"An access violation occurred while reading location 0x....",
I can see the file has been created successfully,so I don't konw why this Error occured.

Answer Source

Don't you really get any diagnostics at all? Every single warning from C compiler is significant, they're usually signs of grave errors! Also, when you do ask on Stack Overflow, please copy any diagnostics from the compiler verbatim into the question.

The problem is here:

fwrite(fin_val, sizeof(fin_val), 1, file);

The prototype of fwrite is

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

The first argument must be a pointer to const void, yet you pass in a uint16_t. It should be &fin_val, so that fwrite gets the address to that variable.

On a related note, fclose; is not a function call, and this too should have produced a diagnostic message in any sane compiler. It should be fclose(file);.

Here's an example output from GCC without warnings:

% gcc -c pcm.c
pcm.c: In function ‘write2PCM’:
pcm.c:10:12: warning: passing argument 1 of ‘fwrite’ makes pointer from integer without a 
             cast [-Wint-conversion]
     fwrite(fin_val,sizeof(fin_val),1,file);
            ^~~~~~~

and here with all warnings enabled:

% gcc -c pcm.c -Wall
pcm.c: In function ‘write2PCM’:
pcm.c:10:12: warning: passing argument 1 of ‘fwrite’ makes pointer from integer without a 
             cast [-Wint-conversion]
     fwrite(fin_val,sizeof(fin_val),1,file);
            ^~~~~~~
In file included from pcm.c:1:0:
/usr/include/stdio.h:717:15: note: expected ‘const void * restrict’ but argument is of 
             type ‘uint16 {aka short unsigned int}’
 extern size_t fwrite (const void *__restrict __ptr, size_t __size,
               ^~~~~~
pcm.c:13:1: warning: statement with no effect [-Wunused-value]
 fclose;}
 ^~~~~~
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download