0

I am trying to read the header info from a wave file but for some reason on the third fread I get a segmentation fault. code:

typedef struct wav_header_info {
    unsigned long samples;
    unsigned int size_of_samples;

    unsigned long  RIFF; // big endian
    unsigned long file_size;// little endian
    unsigned long file_type_header;// big endian
    unsigned long format_chunk_marker;// big endian
    __uint32_t format_data_length;// little endian

    __uint16_t format_type;// little endian
    __uint16_t num_channel;// little endian

    __uint32_t sample_rate;// little endian
    __uint32_t sr_btsps_channel; // little endian, (Sample Rate * BitsPerSample * Channels) / 8
    __uint32_t bits_per_sample_channel; // little endian, (BitsPerSample * Channels) / 8.1 - 8 bit mono2 - 8 bit stereo/16 bit mono4 - 16 bit stereo

    __uint16_t bits_per_sample; // little endian

    __uint32_t data_header; // big endian, Marks the beginning of the data section.
    __uint32_t sizeof_data_section;// little endian


}  wav_header;

int main(int argc, char **argv)
{
    FILE * wav = fopen(argv[1], "rb");
  

    if (wav == NULL)
    {
        printf("no file\n"); 
        exit(1);
    } else {
        printf("File recieved\n");
    }
    
    printf("making wav_info structure\n");
    wav_header  * wav_info;
    initialize_struct(&wav_info);
    // print_file(&wav);
   
    printf("passing wav_info to get_wave_header function\n");
    get_wave_header_info(&wav, &wav_info);
  
    // printf("Printing wave info\n");
    // print_wave_header(&wav_info);
    fclose(wav);
  
}

void get_wave_header_info(FILE ** wav, wav_header **wav_info)
{
    printf("START OF GETTING WAVE HEADER INFO\n");
    unsigned char  buffer_32[4];
    printf("file pointer pos: %ld\n", ftell(*wav));

    //RIFF big endian
    printf("GETTING RIFF\n");
    fread(buffer_32, sizeof(char), 4, *wav);
    (*wav_info)->RIFF = ((buffer_32[0]<<24) | (buffer_32[1])<<16 | (buffer_32[2])<<8 | (buffer_32[3]));
    memset(buffer_32, 0, 4);
    printf("wave riff: %x\n", (*wav_info)->RIFF);
    printf("file pointer pos: %ld\n", ftell(*wav));
   
    //file size little endian
    printf("GETTING FILE SIZE\n");
    fread(buffer_32, sizeof(char), 4, *wav);
    (*wav_info)->file_size = (buffer_32[0]) | (buffer_32[1] << 8) | (buffer_32[2] << 16) | (buffer_32[3] << 24);
    // memset(buffer_32, 0, 4);
    printf("FILE SIZE IS is %d\n", (*wav_info)->file_size);
    printf("file pointer pos: %ld\n", ftell(*wav));

    // file_type_header big endian
    printf("GETTING FILE TYPE HEADER\n");
    
    printf("file pointer pos: %ld\n", ftell(*wav));
    fread(buffer_32, sizeof(char), 4, *wav); //seg fault happens here
    printf("here");
    (*wav_info)->file_type_header = ((buffer_32[0]<<24) | (buffer_32[1])<<16 | (buffer_32[2])<<8 | (buffer_32[3]));
    memset(buffer_32, 0, 4);
    printf("file type header: %s\n",(*wav_info)->file_type_header );
//I want to get the other header information but the seg fault is stopping me from doing that. So there is more to this function
    return;


void initialize_struct(wav_header ** wav_struct)
{
  wav_header *new_struct = malloc(sizeof(*new_struct));
    new_struct->samples = 0;
    new_struct->size_of_samples= 0;
    new_struct->RIFF= 69; 
    new_struct->file_size= 0;
    new_struct->file_type_header= 0;
    new_struct->format_chunk_marker= 0;
    new_struct->format_data_length= 0;
    new_struct->format_type= 0;
    new_struct->num_channel= 0;
    new_struct->sample_rate= 0;
    new_struct->sr_btsps_channel= 0; 
    new_struct->bits_per_sample_channel= 0; 
    new_struct->bits_per_sample= 0; 
    new_struct->data_header= 0; 
    new_struct->sizeof_data_section= 0;
    *wav_struct = new_struct;
}

I'm passing a struct that will hold the wave header information. The weird thing is (at least to me) that if I make another function that picks up where the segmentation fault occurs in get_wave_header_info, then I do not get a segmentation fault. I wondering why that is and why the segmentation fault is happening on the third call of fread.

jpr
  • 63
  • 5
  • `wav_header * wav_info` is not initialized to a place to store the data (at some point you need to allocate some memory or declare a concrete structure on the stack). So the behavior of the program is pretty random and it will probably crash. Using `FILE **` is maybe OK, but pretty unsual, programs usually just use `FILE *`. – Robert Jul 30 '21 at 03:12
  • @Robert I forgot to mention that I was going to write the header information to a file later on...if that's what you mean by place to store data – jpr Jul 30 '21 at 03:33
  • 1
    The correct `printf` format specifier for `unsigned long` as hex is [`"%lx"`](https://stackoverflow.com/a/29509591/3476780) and for dec is [`"%lu"`](https://stackoverflow.com/a/3209915/3476780) – yano Jul 30 '21 at 04:03
  • 1
    And when you get to it, `printf("file type header: %s\n",(*wav_info)->file_type_header );` should be `"%lu"`, `"%s"` is for strings. Your compiler should be giving you warnings about all of these, if it isn't add `-Wall -Wextra` to your build line (for gcc and clang). Clean up all the warnings and see if the problem persists. – yano Jul 30 '21 at 04:11
  • @Robert a bit unorthodox, but `initialize_struct` allocates memory for `wav_info`. `new_struct` is `malloc`ed, then written to `*wav_struct` before the function returns. – yano Jul 30 '21 at 04:34

0 Answers0