使用动态unsigned char数组时出现未知崩溃

时间:2012-08-15 01:44:53

标签: c++ crash char unsigned

有人可以向我解释原因:

unsigned char * buf;
buf = new unsigned char[dataSize];

崩溃了我的c ++程序?它没有给我任何错误,所以我真的迷失了我的程序由于这些代码行而崩溃的原因。提前谢谢!

编辑:这是我正在处理的项目的代码,它正在使用OpenAL,所以如果你想重新编译代码,你将需要它。

#include <cstdlib>
#include <iostream>
#include <Windows.h>
#include <al.h>
#include <alc.h>
#include <vector>

using namespace std;

class SoundSource
{
public:
    ALuint Source;
    ALuint buffer;
    ALuint frequency;
    ALenum format;

    //position
    ALfloat sourcePos[3];
    ALfloat sourceVel[3];
};

ALCcontext * Context;
ALCdevice * Device;
SoundSource sound;

int endWithError(char * msg, int error = 0)
{
    cout << msg << endl;
    while(cin.get() != 10);

    return error;
}

bool initSound()
{
    Device = alcOpenDevice((ALCchar*)"DirectSound3D");
    if(Device == NULL)
        return false;
    else
        {
        Context = alcCreateContext(Device,NULL);
        alcMakeContextCurrent(Context);
        alGetError();
        return true;
        }
    return false;
}

string loadSound(SoundSource s)
{
    char type[4];
    DWORD size, chunkSize;
    short formatType, channels;
    DWORD sampleRate, avgBytesPerSec;
    short bytesPerSample, bitsPerSample;
    DWORD dataSize;

    FILE * fp = NULL;

    fp = fopen("test.wav","rb");

    fread(type, sizeof(char), 4, fp);
    if(!strcmp(type, "RIFF"))
        endWithError("Error: Not RIFF format");

    fread(&size, sizeof(DWORD), 1, fp);

    fread(type, sizeof(char), 4, fp);
    if(!strcmp(type, "WAVE"))
        endWithError("Error: Not WAVE format");

    fread(type, sizeof(char), 4, fp);
    if(!strcmp(type, "fmt "))
        endWithError("Error: Not fmt format");

    fread(&chunkSize, sizeof(DWORD), 1, fp);
    fread(&formatType, sizeof(short), 1, fp);
    fread(&channels, sizeof(short), 1, fp);
    fread(&sampleRate, sizeof(DWORD), 1, fp);
    fread(&avgBytesPerSec, sizeof(DWORD), 1, fp);
    fread(&bytesPerSample, sizeof(short), 1, fp);
    fread(&bitsPerSample, sizeof(short), 1, fp);

    cout << "Chuck size: " << chunkSize << endl;
    cout << "Format type: " << formatType << endl;
    cout << "Channels: " << channels << endl;
    cout << "Sample rate: " << sampleRate << endl;
    cout << "Avg Bytes per sec: " << avgBytesPerSec << endl;
    cout << "Bytes per sample: " << bytesPerSample << endl;
    cout << "Bits per sample: " << bitsPerSample << endl;

    fread(type, sizeof(char), 4, fp);
    if(!strcmp(type, "data"))
        endWithError("Error: No data");

    fread(&dataSize, sizeof(DWORD), 1, fp);

    unsigned char * buf;
    buf = new unsigned char[dataSize];
    fread(buf, sizeof(BYTE), dataSize, fp);

    alGenBuffers(1, &s.buffer);
    alGenSources(1, &s.Source);

    switch(bitsPerSample)
    {
        //8 bit
        case 8:
        {
            switch(channels)
            {
            case 1: s.format = AL_FORMAT_MONO8; break;
            case 2: s.format = AL_FORMAT_STEREO8; break;
            }
        }
        //16 bit
        case 16:
        {
            switch(channels)
            {
            case 1: s.format = AL_FORMAT_MONO16; break;
            case 2: s.format = AL_FORMAT_STEREO16; break;
            }
        }
    }

    alBufferData(s.buffer, s.format, (ALvoid *)buf, dataSize, s.frequency);
    s.sourcePos[0] = 0.0;
    s.sourcePos[1] = 0.0;
    s.sourcePos[2] = 0.0;
    s.sourceVel[0] = 0.0;
    s.sourceVel[1] = 0.0;
    s.sourceVel[2] = 0.0;

    fclose(fp);
    //delete[] buf;

    return "WAVE successfully loaded!";
}

void closeSound()
{
    alDeleteSources(1, &sound.Source);
    alDeleteBuffers(1, &sound.buffer);
    Context = alcGetCurrentContext();
    Device = alcGetContextsDevice(Context);
    alcMakeContextCurrent(NULL);
    alcDestroyContext(Context);
    alcCloseDevice(Device);
    cout << "OpenAL sound closed!" << endl;
}

int main()
{
    string result;

    if(initSound())
    {
        cout << "Sound Context and Device up!" << endl;
        result = loadSound(sound);
        cout << result.c_str() << endl;
        alSourcePlay(sound.Source);
        system("PAUSE");
    }
    else
    {
        {
            cout << "Sound Context and Device not made.." << endl;
            system("PAUSE");
        }
    }

    closeSound();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

// replace this 
if(!strcmp(type, "XXXX"))
    endWithError("Error: Not RIFF format");
// with this 
if(!memcmp(type, "XXXX", 4))
    endWithError("Error: Not RIFF format");

因为类型不是\ 0终止

fread(&chunkSize, sizeof(DWORD), 1, fp);

提示:而不是sizeof(type)使用sizeof(变量名) 例如     fread(&amp; chunkSize,sizeof(chunkSize),1,fp);

如果你以后出于某种原因需要更改变量类型,那么它就不会在你脸上爆炸

fread(&dataSize, sizeof(DWORD), 1, fp);
unsigned char * buf;
buf = new unsigned char[dataSize];
fread(buf, sizeof(BYTE), dataSize, fp);

永远不要假设你读的内容是正确的,而是在分配之前检查dataSize是什么。

避免执行全局变量也是一个好主意,您可以轻松地创建一个包含所需变量的结构,并从函数中返回

struct context_t // or whatever u want to call it
{
  ALCcontext * Context;
  ALCdevice * Device;

};

bool initSound(context_t & c) {}
void closeSound(context_t & c) {}

int main()
{
  context_t context;

  if (initSound(context)) 
  {
  ...
  }
  ..
  closeSound(context);