I am making a basic WAV file loader in order to play basic sound in my program. I have successfully read the entire header with multiple calls to fread, but now I get a strange segmentation fault in fread when trying to load the data buffer.
FILE *fp;
fp = fopen("test.wav","rb");
if (fp)
{
char id[5];
uchar *sound_buffer;
uint size;
// other stuff here for the headers...
int iRead;
iRead = fread(id, sizeof(char), 4, fp);
if (!strncmp(id, "RIFF", 4))
{
iRead = fread(&size, sizeof(uint), 1, fp);
printf("Size : %d.\n", size);
// read other stuff here...
iRead = fread(&data_size, sizeof(uint), 1, fp);
printf("Data size : %d.\n", data_size);
sound_buffer = (uchar *) malloc (sizeof(uchar) * data_size);
printf("Initialized sound buffer.\n");
// The crash is happening on the following fread :
iRead = fread(sound_buffer, sizeof(sound_buffer), 1, fp);
printf("Sound buffer read successfully.\n");
I cannot explain this.
The data_size value might include the data header size (2 * sizeof(uchar)) but I do not think it would crash because of a too big sound_buffer. Also, I have tried to fix data_size to 1 and it still crashes. I have tried with two different .wav files( that both can be played with a music player, so they do have something in their data section).
I have also tried the following with the same result :fread(sound_buffer, sizeof(uchar), data_size, fp);
Has anyone got a clue on what I am doing wrong here ?
size is 21104 and data_size is 21068 with my test.wav file. However, I do not think it is a problem, as I have tested fixing data_size to 1 and I still have a crash.
Your advice is good of course. In my case, it is not as important as in general (I will only play wav files I know the size of, etc...) but anybody reading this page should add some error checks and securities of this kind.
I have added an assert(sound_buffer) and it does not seem to be a problem with the malloc (I have tried also to fill the entire sound_buffer with characters and displayed it).
About the debug output, I have recently switched to linux and am not familiar with gdb and other stuff, so I mostly use printf as much as I can. I am afraid I am good to look for a good gdb tutorial...
Ok nevermind, I tried gdb and it looks it crashes on the next printf :
printf("Sound buffer read successfully.\nLoading into buffer data %d.\n", alBuffer); (I simplified it for the first post, if I had tested it it would have worked, this is so stupid...)
I have no idea why alBuffer (and unsigned int) is causing this here, but I added a simple printf("OK.\n"); before this printf and it outputs OK just before the crash.
Sorry and thank you again, I will now investigate on the new crash, another Segmentation fault while loading this buffer into an OpenAL buffer (which is probably coming from this unsigned int too, even if I do not understand what the problem can be).
Ok, final explanation : all of this is inside a function bLoadWaveFile(char* filename) inside a class Sound with a member alBuffer. I put a Sound* mySound inside another class and tried to call bLoadWaveFile while not having initialized mySound = new Sound().
Stupid, isn't it ?
So the crash is when using alBuffer as it is a member variable. No idea why I could execute the function at all, but as long as I had no membre variable of the class it worked well...
Eventually it worked and I had modified like this, so there should not have this kind of problem : iRead = fread(sound_buffer, sizeof(uchar), data_size, fp);
I am not sure but I suppose it is slower than your solution, however it returns in iRead the data_size read, which can be inferior if the given value is wrong and file size smaller than expected... This can be helpfull when giving buffer to OpenAL after...