首页 > 解决方案 > 尝试在 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) ()

不停地走下去。需要帮助。在此先感谢。

标签: c++stlsegmentation-faultqueue

解决方案


你的 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。


推荐阅读