我很抱歉发布了一个已被多次询问的问题(我刚刚阅读了其中的 10 页),但我找不到解决方案。
我正在开发一个分别使用 OpenGL 和 Portaudio 的多线程图形/音频程序。音频线程使用我为音频处理对象制作的库。SIGSEGV 可能发生 20% 的时间(调试时少得多),并且在使用新的流信息(采样率、矢量大小等)重置音频对象的负载时发生。Code::blocks 每次故障发生时,调试器都会将故障声明为来自不同的地方。
这是音频处理循环:
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。
有什么意见/建议吗?
编辑:
这是一个错误删除的内存问题。应用程序验证程序在错误点使其出现故障,而不是识别为源自其他位置的偶尔故障。问题出在 uVector 流设置函数中,因为该类的目的是用于使用多维数组的音频向量stream->channels
,并可以选择使用一维数组作为控制信号。删除以重新分配内存时,我不小心设置了所有 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;
}
所以它正在删除它不应该访问的内存,这破坏了堆。我很惊讶段错误并没有更频繁地发生,因为这似乎是一个严重的问题。