1.问题描述:
在做一个分布式存储的服务器。服务器在某些异常关闭的场景下,会在析构时,报错:
pure virtual method called, terminate called without an active exception。
服务器析构时,会调用下面这行代码:tx->Commit();
// std::shared_ptr<SeGhBacken> tx;
其声明为:
基类:
class SeGhDB {
public:
virtual int Commit();
}
声明:
class SeGhBacken : public SeGhDB {
int Commit() override;
}
之后服务器会段错误,并报错:
pure virtual method called, terminate called without an active exception
2.问题分析:
段错误,基本都是内存问题。一般是指针被置空,或是指针所指对象已经失效,此处也不例外。这个错误的原因为:在运行期,子类对象被以前析构,或者根本未被构造出来。调用这个函数实现的时候,编译器就调用到了基类的虚函数,如果基类的虚函数未实现,则会报上述错误。
3.问题解决
对象提前被析构或未被构造,通常是因为多线程环境下,线程调度引起的。遇到上述问题,应该首先检查线程内资源的构造和回收状况。
题主遇到的这个问题,正是由此导致。在本项目线程池实现中,遇到退出信号,会抛弃后续任务,导致对象没有被正确构造,从而造成了这个问题,在调整了线程池参数后,问题得到解决。
4.总结:
此问题一般解决方案:
(1)使用new和delete管理对象内存,自己手动控制对象生命周期;
(2)线程内完成对象全生命周期管理,在一个线程内完成对象的构造、调用和析构;
(3)对于同一个线程内的对象,要遵守谁申请,谁释放的内存管理规范;
(4)禁止多级继承。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。