写入新WAV时出现分段错误

时间:2015-04-10 18:21:41

标签: c file-io wav

这是我的代码段失败:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct WAV {
    char chunkId[4];
    unsigned chunkSize;
    char format[4];
    char subChunk1Id[4];
    unsigned subChunk1Size;
    unsigned short audioFormat;
    unsigned short numChannels;
    unsigned sampleRate;
    unsigned byteRate;
    unsigned short blockAlign;
    unsigned short bitsPerSample;
    char subChunk2Id[4];
    unsigned subChunk2Size;
} WAV;

int main() {
    void printwav(const WAV *);
    void openwav(FILE *, WAV *);
    void makewav(FILE *, const WAV *);

    char file[FILENAME_MAX];
    size_t i;
    short
        stereo1,
        stereo2,
        mono1;
    FILE
        *fpstereo,
        *fpmono;
    WAV
        stereo,
        mono;

    openwav(fpstereo, &stereo);

    printwav(&stereo);

    memcpy(&mono, &stereo, sizeof(WAV));

    mono.chunkSize -= stereo.subChunk2Size / 2;
    mono.subChunk2Size /= 2;
    mono.numChannels /= 2;
    mono.byteRate /= 2;
    mono.blockAlign /= 2;

    makewav(fpmono, &mono);

    printwav(&mono);

    for (i = 0; i < mono.subChunk2Size / sizeof(short); i++) {
        fread(&stereo1, sizeof(short), 1, fpstereo);
        fread(&stereo2, sizeof(short), 1, fpstereo);

        mono1 = (stereo1 + stereo2) / 2;

        fwrite(&mono1, sizeof(short), 1, fpmono);
    }

    fclose(fpstereo);
    fclose(fpmono);
}

我的程序输出是:

Enter filepath to stereo WAV: wav11stereo.wav
RIFF
1966116
WAVE
fmt 
16
1
2
44100
176400
4
16
data
1966080

Enter filepath to mono WAV: wav11mono.wav
RIFF
983076
WAVE
fmt 
16
1
1
44100
88200
2
16
data
983040

Segmentation fault: 11

使用一堆printf进行测试后,我发现分段错误发生在for循环内的行fread(&stereo1, sizeof(short), 1, fpstereo);中。我将stereo1称为short而不是short *,所以我不明白为什么会发生这种情况。任何人都可以解释为什么这是错的吗?

1 个答案:

答案 0 :(得分:2)

我想这是你的问题:

void openwav(FILE *, WAV *);
void makewav(FILE *, WAV *);

这样,函数内部的文件打开调用只能在函数内部使用,不会返回给调用者。

通常应该声明如下:

void openwav(FILE **, WAV *);
void makewav(FILE **, WAV *);

并且这样打电话:

openwav(&fpstereo, &stereo);
makewav(&fpmono, &mono);