内存验证线程中的困难任务

时间:2012-06-03 14:20:42

标签: c++ multithreading audio vector

我正在为我的项目创建一个音响系统。每次调用PlayAsync都会在std :: thread回调中创建声音实例。声音数据在此回调中循环进行。当线程继续时,它将声音实例存储在静态向量中。当线程结束(声音完成)时 - 它删除声音实例并减少实例计数。当应用程序结束时 - 它必须立即停止所有声音,向每个声音周期发送中断。

问题在于保持这些声音的数组。我不确定,但我认为矢量不是这个目的的正确选择..这是一个代码。

void gSound::PlayAsync()
{
    std::thread t(gSound::Play,mp_Audio,std::ref(*this));
    t.detach();
}
    HRESULT gSound::Play(IXAudio2* s_XAudio,gSound& sound)
{                
    gSound* pSound = new gSound(sound);   
    pSound->m_Disposed = false;         

    HRESULT hr;      
    // Create the source voice
    IXAudio2SourceVoice* pSourceVoice;
    if( FAILED( hr = s_XAudio->CreateSourceVoice( &pSourceVoice, pSound->pwfx ) ) )
    {
        gDebug::ShowMessage(L"Error creating source voice");      
        return hr;
    }

    // Submit the wave sample data using an XAUDIO2_BUFFER structure
    XAUDIO2_BUFFER buffer = {0};
    buffer.pAudioData = pSound->pbWaveData;
    buffer.Flags = XAUDIO2_END_OF_STREAM;  // tell the source voice not to expect any data after this buffer
    buffer.AudioBytes = pSound->cbWaveSize;

    if( FAILED( hr = pSourceVoice->SubmitSourceBuffer( &buffer ) ) )
    {
        gDebug::ShowMessage(L"Error submitting source buffer");
        pSourceVoice->DestroyVoice();   
        return hr;
    }

    hr = pSourceVoice->Start( 0 );     

    // Let the sound play
    BOOL isRunning = TRUE;
    m_soundInstanceCount++;     
    mp_SoundInstances.push_back(pSound); #MARK2
    while( SUCCEEDED( hr ) && isRunning && pSourceVoice != nullptr && !pSound->m_Interrupted)
    {    
        XAUDIO2_VOICE_STATE state;
        pSourceVoice->GetState( &state );
        isRunning = ( state.BuffersQueued > 0 ) != 0;     
        Sleep(10);
    }   
    pSourceVoice->DestroyVoice();   
    delete pSound;pSound = nullptr; //its correct ??
    m_soundInstanceCount--; 
    return 0;    
}

void gSound::InterrupAllSoundInstances()
{
    for(auto Iter = mp_SoundInstances.begin(); Iter != mp_SoundInstances.end(); Iter++)
    {
        if(*Iter != nullptr)//#MARK1
        {
        (*Iter)->m_Interrupted = true;
        }
    }
}

在主应用程序循环立即之后,我在处理声音对象之前调用应用程序类。

    gSound::InterrupAllSoundInstances();
while (gSound::m_soundInstanceCount>0)//waiting for deleting all sound instances in threads
{

}

问题:

所以#MARK1 - 如何检查向量中的内存验证?我没有经验。并且在尝试检查无效内存时会出错(它不等于null)

和#MARK2 - 如何正确使用向量?或者也许矢量是不好的选择?每次我创建声音实例时它都会增加大小。这不好。

1 个答案:

答案 0 :(得分:1)

典型问题:

delete pSound;
pSound = nullptr; // issue

这不符合您的想法。

它会将pSound有效地设置为null,但是同样指针的其他副本(矢量中至少有一个)也不会被取消。这就是您在nullptr中找不到vector的原因。

相反,您可以将索引注册到向量中并使其无效:mp_SoundInstances[index] = nullptr;

然而,我担心你根本不理解记忆处理而你缺乏结构。对于内存处理,没有细节很难说,你的系统看起来很复杂,我担心它会说太长时间无法解释。对于结构,您应该阅读一下Observer模式。