何度も寄せられた質問を投稿して申し訳ありません (10 ページを読んだだけです) が、解決策が見つかりません。
OpenGL と Portaudio をそれぞれ使用して、マルチスレッドのグラフィック/オーディオ プログラムに取り組んでいます。オーディオ スレッドは、オーディオ処理オブジェクト用に私が作成しているライブラリを使用します。SIGSEGV はおそらく 20% の確率で発生し (デバッグ時ははるかに少ない)、オーディオ オブジェクトのロードを新しいストリーム情報 (サンプル レート、ベクター サイズなど) でリセットするときに発生します。Code::blocks Debugger は、障害が発生するたびに、別の場所から発生したものとして障害を示します。
これはオーディオ処理ループです。
while(true){
stream->tick();
menuAudio.tick();
{
boost::mutex::scoped_lock lock(*mutex);
if(channel->AuSwitch.resetAudio){
uStreamInfo newStream(channel->AuSwitch.newSrate,
channel->AuSwitch.newVSize, channel->AuSwitch.newChans);
menuAudio.resetStream(&newStream);
(*stream) = newStream;
menuAudio.resetStream(stream);
channel->AuSwitch.resetAudio = false;
}
}
}
オーディオをリセットするように伝えるグラフィックス スレッドからの情報をチェックし、パッチ オブジェクトの resetStream 関数を実行します。これは基本的にオーディオ オブジェクトのベクトルであり、それぞれを実行します。
void uPatch::resetStream(uStreamInfo* newStream)
{
for(unsigned i = 0; i < numObjects; ++i){
/*This is where it reports this error: Program received signal SIGSEGV,
Segmentation fault. Variables: i = 38, numObjects = 43 */
objects[i]->resetStream(newStream);
}
}
SIGSEGV が別の場所から発信されていると表示されることもありますが、デバッガーで実行したときにエラーが発生することはめったにないため、これだけが発生する可能性があります。
非常に多くのオブジェクトがあるため、すべてのリセット コードを投稿することはしませんが、例として:
void uSamplerBuffer::resetStream(uStreamInfo* newStream)
{
audio.set(newStream, false);
control.set(newStream, true);
stream = newStream;
incr = (double)buffer->sampleRate / (double)stream->sampleRate;
index = 0;
}
audio.set コードは次のとおりです。
void uVector::set(uStreamInfo* newStream, bool controlVector)
{
if(vector != NULL){
for(unsigned i = 0; i < stream->channels; ++i)
delete[] vector[i];
delete vector;
}
if(controlVector)
channels = 1;
else
channels = newStream->channels;
vector = new float*[channels];
for(unsigned i = 0; i < channels; ++i)
vector[i] = new float[newStream->vectorSize];
stream = newStream;
this->flush();
}
私の最善の推測では、実際には多数のオブジェクトでのみ発生し、それぞれが個別に正常に実行されるため、これはスタック オーバーフローの問題であると考えられます。とはいえ、オーディオ ストリーム自体は正常に動作し、同様の方法で実行されます。また、ループはobjects[i]->resetStream(newStream);
各メンバー関数の後にスタックをポップする必要があるため、SIGSEGV になる理由がわかりません。
所見/推奨事項はありますか?
編集:
これは、誤って削除されたメモリの問題でした。Application Verifier は、他の場所から発生したと特定された時折の障害ではなく、エラーの時点で障害を起こしました。問題は、uVector ストリーム設定関数にありました。このクラスの意図は、stream->channels
制御信号に 1 次元配列を使用するオプションを使用して、多次元配列を使用するオーディオ ベクトルを対象としているためです。メモリを再割り当てするために削除するときに、ストリーム->チャネルを使用して削除するタイプに関係なく、すべてのuVectorを誤って設定しました。
if(vector != NULL){
for(unsigned i = 0; i < stream->channels; ++i)
delete[] vector[i];
delete vector;
}
あるべき場所:
if(vector != NULL){
for(unsigned i = 0; i < this->channels; ++i)
delete[] vector[i];
delete vector;
}
そのため、アクセスしてはならないメモリを削除していたため、ヒープが破損していました。深刻な問題のように見えるので、セグメンテーション違反が定期的に発生していないことに驚いています。