c++ - 尝试在 C++ 中实现固定大小的队列时出现分段错误
问题描述
我想实现一个固定大小的队列,我可以很容易地使用一个结构体,该结构体具有一个队列作为数据成员之一和一个负责队列推送部分的成员函数,但我想通过继承来尝试它像这样排队。
template<typename T>
struct f_queue : public queue<T>{
int n;
T prev;
f_queue(int n_):
n(n_){}
void push(T data){
if(this->size() < this->n){
this->push(data);
}else{
prev = this->front();
this->pop();
this->push(data);
}
}
};
这编译得很好,但由于某种原因,它给出了分段错误,gdb 说
程序收到信号 SIGSEGV,分段错误。0x0000555555555862 在 std::_Deque_iterator<int, int&, int*>::_S_buffer_size() ()
不太确定这应该是什么意思?当尝试进行回溯时,输出结果为
#9913 0x0000555555554ec6 in f_queue<int>::push(int) ()
#9914 0x0000555555554ec6 in f_queue<int>::push(int) ()
#9915 0x0000555555554ec6 in f_queue<int>::push(int) ()
#9916 0x0000555555554ec6 in f_queue<int>::push(int) ()
#9917 0x0000555555554ec6 in f_queue<int>::push(int) ()
#9918 0x0000555555554ec6 in f_queue<int>::push(int) ()
#9919 0x0000555555554ec6 in f_queue<int>::push(int) ()
不停地走下去。需要帮助。在此先感谢。
解决方案
你的 push 函数总是递归到自身:
void push(T data){
if(this->size() < this->n){
this->push(data);//HERE f_queue::push is called
}else{
prev = this->front();
this->pop();
this->push(data);//HERE f_queue::push is called
}
}
您可能打算调用基类的推送:
void push(T data){
if(this->size() < this->n){
queue<T>::push(data);
}else{
prev = this->front();
this->pop();
queue<T>::push(data);
}
}
请注意,STL 容器并不意味着公开派生。它们没有虚拟析构函数,因此请确保您永远不要通过基类指针/引用进行删除。
编辑
非虚拟析构函数意味着以下代码是危险的:
std::queue<T>* base = new f_queue<T>();
delete base;//Call std::queue<T>::~queue();
没有办法强制调用正确的析构函数。使f_queue
' 的析构函数 virtual 无济于事。但是,只要您从不通过指向基类的指针删除,从任何类派生都没有错。
一种强制执行的方法是使用私有继承,但我猜你首先使用继承来保留大部分std::queue
的 API。
推荐阅读
- javascript - 如何在两个独立标签之间获取 HTML 元素
- graphql - 所需类型“Int!”的 GraphQL“$id” 没有提供
- google-cloud-platform - 如何从 Google 云调度程序定期触发 Google Cloud Build 作业
- php - Doctrine 在水合过程中添加了额外的查询,导致“正常”一对一和自引用关系出现 n+1 问题
- wordpress - 批量删除某些分类的所有术语(Wordpress)
- neural-network - 如何将 MLP 问题转换为 ARFF 文件
- python - 使用 np.loadtxt() 加载数据时出现内存错误
- unity3d - 粒子从一个角度看是黑色的,从另一个角度看是正常的
- google-sheets - 在 Google 电子表格的气泡图中,如何将气泡大小设置为项目的频率?
- c# - WPF 中的嵌入式 Unity 应用程序,鼠标单击后失去焦点(已解决)