尝试在 C++ 中实现固定大小队列时出现分段错误
Segmentation fault while trying to implement fixed size queue in 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 说
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555862 in std::_Deque_iterator<int, int&,
int*>::_S_buffer_size() ()
不太确定那是什么意思?当尝试执行 backtrace 时,输出结果为
#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) ()
不停歇走不完。需要提前 this.Thanks 的帮助。
您的推送函数总是递归到自身:
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
}
}
您可能打算调用基地 class 的推送:
void push(T data){
if(this->size() < this->n){
queue<T>::push(data);
}else{
prev = this->front();
this->pop();
queue<T>::push(data);
}
}
请注意,STL 容器并不是公开派生的。它们没有虚拟析构函数,因此请确保您永远不会通过基数删除 class pointer/reference.
编辑
Non-virtual 析构函数意味着以下代码是危险的:
std::queue<T>* base = new f_queue<T>();
delete base;//Call std::queue<T>::~queue();
无法强制调用正确的析构函数。将 f_queue
的析构函数设为虚拟函数无济于事。但是,只要您从不通过指向基 class 的指针进行删除,从任何 class.
派生就没有错
实现这一点的一种方法是使用私有继承,但我猜您首先使用继承来保留大多数 std::queue
的 API。
我想实现一个固定大小的队列,我可以很容易地使用一个将队列作为数据成员之一的结构和一个负责队列的推送部分的成员函数来完成,但我更想通过像这样继承队列来尝试一下。
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 说
Program received signal SIGSEGV, Segmentation fault. 0x0000555555555862 in std::_Deque_iterator<int, int&, int*>::_S_buffer_size() ()
不太确定那是什么意思?当尝试执行 backtrace 时,输出结果为
#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) ()
不停歇走不完。需要提前 this.Thanks 的帮助。
您的推送函数总是递归到自身:
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
}
}
您可能打算调用基地 class 的推送:
void push(T data){
if(this->size() < this->n){
queue<T>::push(data);
}else{
prev = this->front();
this->pop();
queue<T>::push(data);
}
}
请注意,STL 容器并不是公开派生的。它们没有虚拟析构函数,因此请确保您永远不会通过基数删除 class pointer/reference.
编辑
Non-virtual 析构函数意味着以下代码是危险的:
std::queue<T>* base = new f_queue<T>();
delete base;//Call std::queue<T>::~queue();
无法强制调用正确的析构函数。将 f_queue
的析构函数设为虚拟函数无济于事。但是,只要您从不通过指向基 class 的指针进行删除,从任何 class.
实现这一点的一种方法是使用私有继承,但我猜您首先使用继承来保留大多数 std::queue
的 API。