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

标签 c++ multithreading audio vector

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

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

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 - 如何检查 vector 中的内存验证?我没有这方面的经验。并在尝试检查无效内存时出错(它不等于 null)

还有#MARK2 - 如何正确使用 vector ?或者 vector 是不好的选择?每次我创建声音实例时,它都会增加大小。这不好。

最佳答案

典型问题:

delete pSound;
pSound = nullptr; // issue

这和你想的不一样。

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

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

但是,恐怕您根本就没有很好地理解内存处理并且缺乏结构。对于内存处理,没有细节很难说,而且你的系统看起来很复杂,恐怕解释起来会太长。对于结构,您应该阅读一些关于 Observer 模式的内容。

关于c++ - 线程内困难任务中的内存验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10871088/

相关文章:

c++ - inet_ntop 返回不存在的地址

c++ - ADODB 记录集中的访问冲突关闭

c++ - 读取复杂文件以对 <string,pair<map<string,string> string>> C++

java - 这种嵌套映射结构对于多线程读取安全吗?

c++ - 如何(字面意思)创建一个 makefile(用于 linux 中的 c)?

android - 如何使 IntentService 的线程保持 Activity 状态?

c - 使用没有互斥锁的线程增加全局变量会奇怪地返回正确的值

c++ - 从二进制数据恢复 MP3 文件

android - 使用 FFT 和 Complex 类获取频率 wav 音频

iphone - AudioSessionInitialize返回难以理解的错误代码