C++ 在C+中查找总线错误/Seg故障时出现故障+;和Linux

C++ 在C+中查找总线错误/Seg故障时出现故障+;和Linux,c++,linux,pthreads,segmentation-fault,bus-error,C++,Linux,Pthreads,Segmentation Fault,Bus Error,我有一个程序,处理在本地网络上以UDP数据包广播的数据 我当前的程序有两个线程:UI线程和工作线程。工作线程只是侦听数据包,解析它们,并使它们可供UI线程用于显示和处理。我当前的实现工作得很好。然而,由于种种原因,我试图用面向对象的方法在C++中重新编写程序。 当前工作程序使用以下命令初始化第二个线程: pthread_t netThread; net = NetCom::initUdpRx(host,port); pthread_create(&netThread, NULL, get

我有一个程序,处理在本地网络上以UDP数据包广播的数据

我当前的程序有两个线程:UI线程和工作线程。工作线程只是侦听数据包,解析它们,并使它们可供UI线程用于显示和处理。我当前的实现工作得很好。然而,由于种种原因,我试图用面向对象的方法在C++中重新编写程序。 当前工作程序使用以下命令初始化第二个线程:

pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, getNetSpike, (void *)NULL);
以下是新线程调用的
getNetSpike
函数:

void *getNetSpike(void *ptr){
    while(true)
    {
        spike_net_t s;
        NetCom::rxSpike(net, &s);
        spikeBuff[writeIdx] = s;
        writeIdx = incrementIdx(writeIdx);
        nSpikes+=1;
        totalSpikesRead++;
    }
} 
现在,在我的新OO版本的程序中,我以大致相同的方式设置了第二个线程:

void SpikePlot::initNetworkRxThread(){
    pthread_t netThread;
    net = NetCom::initUdpRx(host,port);
    pthread_create(&netThread, NULL, networkThreadFunc, this);
}
但是,由于
pthead\u create
使用指向void函数的指针,而不是指向对象成员方法的指针,因此我需要创建这个简单的函数来包装
SpikePlot.getNetworSpikePacket()
方法

void *networkThreadFunc(void *ptr){
        SpikePlot *sp = reinterpret_cast<SpikePlot *>(ptr);

    while(true)
    {
        sp->getNetworkSpikePacket();
    }
}
这两个实现的代码几乎相同,但第二个实现(OO版本)在读取第一个数据包后由于SegFault或BusError崩溃。使用
printf
我缩小了导致错误的行:

spikeBuff[writeIdx] = s;
就我个人而言,我不明白为什么它会导致我的程序崩溃

我做错了什么

更新: 我将
spikeBuff
定义为该类的私有成员:

class SpikePlot{
private:
    static int const MAX_SPIKE_BUFF_SIZE = 50;
    spike_net_t spikeBuff[MAX_SPIKE_BUFF_SIZE];
       ....
}
然后在SpikePlot构造函数中调用:

bzero(&spikeBuff, sizeof(spikeBuff));
并设置:

writeIdx =0;
更新2:好的,我的索引变量发生了一些非常奇怪的事情。为了测试他们的理智,我将
getNetworkSpikePacket
更改为:

void TetrodePlot::getNetworkSpikePacket(){
    printf("Before:writeIdx:%d nspikes:%d totSpike:%d\n", writeIdx, nSpikes, totalSpikesRead);

    spike_net_t s;
    NetCom::rxSpike(net, &s);
//  spikeBuff[writeIdx] = s;
    writeIdx++;// = incrementIdx(writeIdx);
//  if (writeIdx>=MAX_SPIKE_BUFF_SIZE)
        // writeIdx = 0;
    nSpikes += 1;
    totalSpikesRead += 1; 
    printf("After:writeIdx:%d nspikes:%d totSpike:%d\n\n", writeIdx, nSpikes, totalSpikesRead);
}
我将以下输出输出到控制台:

Before:writeIdx:0 nspikes:0 totSpike:0
After:writeIdx:1 nspikes:32763 totSpike:2053729378

Before:writeIdx:1 nspikes:32763 totSpike:2053729378
After:writeIdx:1 nspikes:0 totSpike:1

Before:writeIdx:1 nspikes:0 totSpike:1
After:writeIdx:32768 nspikes:32768 totSpike:260289889

Before:writeIdx:32768 nspikes:32768 totSpike:260289889
After:writeIdx:32768 nspikes:32768 totSpike:260289890

这个方法是唯一的方法,我在这里更新它们的值(除了构造函数之外,我在构造函数中将它们设置为0)。这些变量的所有其他用途都是只读的。

如果要在任何位置分配
spikeBuff
数组,请确保分配了足够的存储空间,以便
writeIdx
不是越界索引


我还要检查
initNetworkRxThread
是否在
spikePlot
对象的分配实例上被调用(而不仅仅是在声明的指针上)

看来您重新解释的演员阵容可能会导致一些问题。调用pthread_create时,传递的是“this”,它是一个SpikePlot*,但在networkThreadFunc中,您将它强制转换为一个TetrodePlot*


SpikePlot和TetrodePlot相关吗?你发布的内容中没有提到这一点。

这可能是错误的,但

您似乎将等待循环逻辑从方法中移出并放入静态包装器中。在没有任何东西保持工作线程打开的情况下,可能该线程在您第一次等待UDP数据包后终止,所以第二次,静态方法中的sp现在指向一个已离开作用域并已被破坏的实例


在调用它的getNetworkSpikePacket()之前,你能在包装器中断言(sp)吗?

我在这里冒险说,你所有的问题都是由spike\u net\t数组的归零引起的


<>在C++中,你不能用非[插入]字来构造对象,比如“这里”成员。i、 e.如果对象包含复杂对象(标准字符串、向量等),则不能将其归零,因为这会破坏在构造函数中完成的对象初始化。

spikeBuff的定义是什么?在哪里初始化了
writeIdx
以及
incrementIdx
是什么样子?下一次尝试:在访问失败之前检查writeIdx的值。如果出现问题,它可能是负数或一个巨大的正数。那么
incrementIdx()
呢?而
writeIdx
在哪里声明?它是全局的吗?@BjoernD,我试着打印出writeIdx,并在故障行之前将其设置为0,并且它始终处于正确的值。大概您在崩溃之前打印出了writeIdx的值,并且它在数组边界内。是吗?是的,我甚至在使用它之前就尝试过将它设置为0,同样的问题发生在OOPS。。。很抱歉,我的代码不是这样的,我在复制/粘贴代码时出错,因此我在问题中修复了代码。好的,我认为我不需要这样做,但我在事情不起作用时添加了它。不是确切的问题,但它为我指出了解决错误的正确方向。确切的问题是什么?想要编辑问题或答案并显示出哪里出了问题?
Before:writeIdx:0 nspikes:0 totSpike:0
After:writeIdx:1 nspikes:32763 totSpike:2053729378

Before:writeIdx:1 nspikes:32763 totSpike:2053729378
After:writeIdx:1 nspikes:0 totSpike:1

Before:writeIdx:1 nspikes:0 totSpike:1
After:writeIdx:32768 nspikes:32768 totSpike:260289889

Before:writeIdx:32768 nspikes:32768 totSpike:260289889
After:writeIdx:32768 nspikes:32768 totSpike:260289890