小弟现在在做一个音频聊天的项目。声音现在可以正常播放,但是如果窗口间切换的话,
会产生 "x7c938994 处最可能的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突"的异常。
是不是因为窗口切换的时候产生其它消息,声音来不及播放就被新来的数据破坏掉了呢。
数据接收用的是while中recvfrom()来完成的。
我分步执行了一下,waveOutWrite()函数执行后,不管是否播完声音,程序会继续执行,接收数据。
感觉这个地方有问题,却没有想到 什么好方法解决。在没有播放完之前不再接收数据。整体逻辑比较混乱,还请大家帮帮忙

解决方案 »

  1.   

    在debug下,调试,出错时用重试是否能够找到崩溃点?
      

  2.   

    因为这样的操作
    *ptr = xxxx;  // 此时 ptr 为 NULL
    造成的debug模式下调试, 弹出那个对话框的时候, 点重试, 看看是在哪个地方崩溃的
      

  3.   

    同意楼上,debug单步看一下指针的值另外,考虑是否可以用多线程,或者用缓冲区把数据存起来
      

  4.   

    找不到崩溃点啊,就是在窗口切换的时候突然就没声音了,
     产生“0xC0000005: 读取位置 0x00000000 时发生访问冲突"
    如果把waveOutWrite()函数注销掉,就没有问题了,如果我只是接收一段声音,
    接收后再播放也没有问题,只有 实时播放时有这个问题,所以我 怀疑是不是
    waveOutWrite()使用上有问题
      

  5.   

    那你waveOutWrite这段使用代码是怎么写的?
      

  6.   

    hua_yang :
    我感觉waveOutWrite()函数播放 的 时候就 已经开了 一个 现成播放了,因为走到 这个 函数的 时候 并没有停,
    又往下面走了,我 现在设了二个缓存,一个接收满,另一个再接收,2个循环用,缓存越大,问题出现的可能性越低,
    但是时间长了还会出现
      

  7.   

    // 客户端监听线程
    DWORD WINAPI CLIENT_THREAD_UDP(LPVOID lpParameter)
    {
      while(true)
      {
    recvfrom(clientData->clientSock,(char*)transData,sizeof(TRANS_DATA),0,(sockaddr*)&servAddr,&servAddrLen);
      }
     if(transData->type==TYPE_SERVER_DATA)
     {
     // 播放声音
        mainWnd->PlayAudio(transData->data); }
    }
    主线程中播放
    // 声音播放
    void CUdpAudioDlg::PlayAudio(char* data)
    {
    // 播放帧设定
    m_wHDROut.dwBufferLength=SIZE_AUDIO_FRAME;
    m_wHDROut.lpData=data;
    m_wHDROut.dwFlags=WHDR_BEGINLOOP | WHDR_ENDLOOP ;
    m_wHDROut.dwLoops=1; // 播放
    waveOutPrepareHeader(m_hwOut,&m_wHDROut,sizeof(WAVEHDR));
    waveOutWrite(m_hwOut,&m_wHDROut,sizeof(WAVEHDR));}
      

  8.   

    线程中不要直接播放 
        mainWnd->PlayAudio(transData->data); 发送消息等PostMessage到主线程,让主线程来播放,调用等
      

  9.   

    oyljerry :
    按照PostMessage到主线程的方式,我试验了几次,产生新的异常有几次是
    在系统函数void __cdecl AtlTraceVU()中HEAP[UdpAudio.exe]: HEAP: Free Heap block 1706f0 modified at 170718 after it was freed
    Windows 已在 UdpAudio.exe 中触发一个断点。其原因可能是堆被损坏,这也说明 UdpAudio.exe 中或它所加载的任何 DLL 中有 bug。也有几次是
    HEAP[UdpAudio.exe]: Invalid Address specified to RtlGetUserInfoHeap( 00150000, 00170C40 )
    Windows 已在 UdpAudio.exe 中触发一个断点。其原因可能是堆被损坏,这也说明 UdpAudio.exe 中或它所加载的任何 DLL 中有 bug。
      

  10.   

    问题解决了,还是waveOutWrite ()播放的问题,参考网上的一个程序修改了一下,感谢大家帮忙 ,现在结贴
      

  11.   

    楼主给出的问题,自己后来又搞定了,可是没有告诉大家,为此楼上三位只好追问。我也遇到了这个问题,后来我也解决了。我来说一下我的解决方法吧。之前由于我认为把wave的数据保存下来就行了,那个LPWAVEHDR只是临时数据,使用waveOutWrite之后就不用管了,因此我只用了一个WAVEHDR类型的局部变量。然而,那个waveOutWrite调用的时候,并不把那个LPWAVEHDR参数指向的内容拷贝之后再播放,而是直接使用LPWAVEHDR参数所指向的那段内存空间,整个播放过程都是如此。大家应该都知道,函数的局部变量是保存在栈里面的,当该函数调用完之后,那些局部变量都会被销毁,因此waveOutWrite中LPWAVEHDR参数所指向的那段内存空间就失效了,所以才会出现0xC0000005的错误。明白了上面的问题,解决起来就很容易了,保证那个WAVEHDR在整个播放过程中一直存在就行了。由于我把这个wav文件的播放封装成了一个类,因此我就把那个WAVEHDR作为这个类的成员