对象列表分割错误
Segmentation fault in list of objects
我没想到这会这么难,但我有以下程序:在多线程环境中(使用ACE-Framework和OpenMP),我使用观察者模式。
在观察者-控制器-线程(ActiveObject)的初始化例程中,我创建了一个向量ConcreteObservers(用于通知它们离散的作业),如下所示:
mResynthesisVec.assign(cMaxEDTDetection, ConcreteResynthesis(pClientObj));
到目前为止,我在类中只使用了标准的pod类型,所以标准的复制构造函数没有产生任何问题。但是今天我用std::complex类型的向量扩展了concreteobserver类。我认为向量已经具有类型复制构造函数能力,但我得到的只是分割错误,就在创建ConcreteObserver之后。那么为什么这不起作用呢?编辑:线程Resynthesis是一个ACE::ActiveObject(线程)并维护观察者。这个线程有一个Subject mEventMonitor作为成员变量,它控制所有具体观察者(ConcreteResynthesis),这些观察者是在Resynthesis的初始化例程中创建并存储在std::vector中(如上所示)。一旦要执行的任务通过TCP从另一个程序来,Resynthesis在Subject中注册所需数量的具体观察者,并分别"通知"他们要做的工作。
typedef std::complex<float> TComplexType;
typedef std::vector<TComplexType> TFFTContainer;
typedef TFFTContainer::iterator TFFTContIter;
typedef std::vector<float> TWindowContainer;
class ConcreteResynthesis: public Subject::Observer {
public:
ConcreteResynthesis();
ConcreteResynthesis(TCPClient * client);
virtual ~ConcreteResynthesis();
virtual void Notify(TBinPos value, int workSignal, int shotCntr, int shots); /// Function called by observed Subject
... some methods
private:
TBinPos mPos; ///< Last observed value
TCPClient * pClientObj;
TFFTContainer mFFTDataCont; //makes the problem
fftwf_plan mFFTWPlan;
unsigned int mCurrentLength;
unsigned int mSignalPos;
TFFTContainer tFullSignal; //makes the problem
};
ConcreteResynthesis的构造函数如下所示
ConcreteResynthesis::ConcreteResynthesis(TCPClient *client) : ///<avaroa(0),
pClientObj(client) {
fftwf_init_threads(); ///< does only need to be called once, so do it here
}
ConcreteResynthesis
中的虚析构函数为空在Resynthesis中定义工作区域后,我这样通知具体观察者:
for (int i = 0; i < iSignalCntr; ++i)
mEventMonitor.ConcreteNotify(pClientObj->GetBinPositions(i), i, sBurstCounter, sBursts);
问题是观察者是在Resynthesis的初始化例程中创建的,所以直到我得到一个工作,只有ConcreteResynthesis的构造函数被调用。但是对于类中的向量,在创建第一个具体观察者
之后,我得到了分割错误EDIT2 按照建议,我实现了复制构造函数、析构函数和赋值操作符。但我还是有分割错误。在析构函数中,我将指针设置为零,因为删除是由另一个线程负责的。下面你可以看到"3原则"的实现:
赋值操作符(与复制构造函数几乎相同,但不返回this指针,也不使用if语句)
ConcreteResynthesis & ConcreteResynthesis::operator=(const ConcreteResynthesis & rhs) {
if (this != &rhs) {
mRange = rhs.mRange;
pClientObj = rhs.pClientObj;
pDataPool = rhs.pDataPool;
tFullSignal = rhs.tFullSignal;
mPos = rhs.mPos; ///< Last observed value
mFFTDataCont = rhs.mFFTDataCont;
mZeroBytes2Add = rhs.mZeroBytes2Add;
mNextPowOf2 = rhs.mNextPowOf2;
//mFile = rhs.mFile;
mFFTWPlan = rhs.mFFTWPlan;
mFFTW_WisdomString = 0;
//mutable ACE_Thread_Mutex mMutex; ///< A mutex to guard the value
mCurrentLength = rhs.mCurrentLength;
mSignalPos = rhs.mSignalPos;
}
return *this;
}
虚拟析构函数:
ConcreteResynthesis::~ConcreteResynthesis() {
pClientObj = 0;
pDataPool = 0;
}
这可能不能解决您的所有问题,但您应该做的一件事是将您的TCPClient
指针作为std::shared_ptr
而不是原始指针。
根据您的描述,由于您使用std::vector<ConcreteResynthesis>
,您确实在实例之间共享指针。您还提到,在完成所有操作后,您正在手动释放线程管理器中的指针。这似乎是std::shared_ptr
的用例。
你的ConcreteResynthesis
类有以下成员:
TBinPos mPos; ///< Last observed value
TCPClient* pClientObj;
TFFTContainer mFFTDataCont; //makes the problem
fftwf_plan mFFTWPlan;
unsigned int mCurrentLength;
unsigned int mSignalPos;
TFFTContainer tFullSignal; //makes the problem
改成:
#include <memory>
//...
TBinPos mPos; ///< Last observed value
std::shared_ptr<TCPClient> pClientObj;
TFFTContainer mFFTDataCont; //makes the problem
fftwf_plan mFFTWPlan;
unsigned int mCurrentLength;
unsigned int mSignalPos;
TFFTContainer tFullSignal; //makes the problem
当调用ConcreteResynthesis
对象实例的副本时,共享指针将增加引用计数。vector中的每个对象将使用相同的单个指针。当最后一个使用共享指针的实体被销毁(销毁使引用计数为0)时,指针最终被删除。
由于所有的复制和析构都在std::vector
内部进行,std::shared_ptr
成员负责所有的工作,这些工作是析构函数(现在不再需要)试图以一种不优雅的方式完成的(以一种"穷人的移动构造函数"类型的方式将指针设置为0)。
除此之外,您不需要用户定义的复制构造函数、赋值操作符或析构函数,从而使代码更干净,更不容易出现错误。
请注意,有了所有这些,我假设基类Subject::Observer
也是可复制的,没有问题。
- C++映射分割错误(核心转储)
- 由cin中的字符串中未捕获空白引起的分割错误
- 删除映射和分割错误中的一个过去结束元素
- 在指向函数中读取变量时出现分割错误
- 在链表中的第 n 位插入显示分割错误
- 较高值 n 的分割错误(例如 n=999997)
- 尝试通过memcpy复制大尺寸浮点向量时的分割错误
- 分割错误:向量中的擦除功能
- 向量向量的分割错误
- 我在C++中编写了一个方法来打印树类的预序,但它显示了分割错误
- C ++分割错误,为什么使用"long long"我没有得到答案?
- 在尝试使用递归查找集合子集的总数时,我遇到了分割错误
- 分割错误 11:尝试使用 cin 输入 B[1] 时
- 集合布局上的 Qt 分割错误
- 高达20亿的筛子会产生分割错误
- G :内部编译器错误:分割故障(程序CC1PLUS) - 我在哪里开始
- 二进制搜索树操作程序错误:分割故障(核心倾倒)
- 在给出正确的输出后,给出错误分割错误(核心转储)
- 得到错误分割错误(核心转储)进程返回139 (0x8B)
- 内部编译错误:分割错误在gcc.发送可变模板到struct时