-3

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.

马慧超
  • 183
  • 1
  • 10

2 Answers2

3

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;}
 ^~~~~~
0

fwrite expects a pointer to the data you want to write.

This will write fin_val to the file in binary mode:

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

Your compiler should have warned you that you provided an integer value instead of a pointer. You should turn up the warning level of your compiler. If you use gcc, add -Wall to the compiler command line.

Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • thanks ,I am not very familiar with c,now I know what's the problem,thanks very much. – 马慧超 Jul 27 '17 at 08:28
  • The important thing is that you turn on/up compiler warnings. It will help you a lot in the future. The compiler can find many (but far from all) coding mistakes. – Klas Lindbäck Jul 27 '17 at 08:38
  • I will remember that and improve myself,but there is a little error message in vs but a lot in gcc.. – 马慧超 Jul 27 '17 at 08:41
  • @马慧超 In Visual Studio I suggest you use /W4 for new code. See https://learn.microsoft.com/sv-se/cpp/build/reference/compiler-option-warning-level – Klas Lindbäck Jul 27 '17 at 10:22
  • that's a good idea ,I will try that,thanks ,You are very enthusiastic. – 马慧超 Jul 27 '17 at 10:38