【问题标题】:Segmentation fault while trying to implement fixed size queue in C++尝试在 C++ 中实现固定大小的队列时出现分段错误
【发布时间】:2020-08-28 11:21:16
【问题描述】:

我想实现一个固定大小的队列,我可以很容易地使用一个结构体,该结构体具有一个队列作为数据成员之一和一个负责队列推送部分的成员函数,但我想尝试一下像这样继承队列。

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::_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-&gt;push(data); 引入了递归(可能是无意的)。我假设,您实际上希望 queue&lt;T&gt;::push(data); 引用基类的 push()

标签: c++ stl segmentation-fault queue


【解决方案1】:

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

你可能是想调用基类的 push:

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 的析构函数设为虚拟将无济于事。但是,只要你从不通过指向基类的指针删除,从任何类派生都没有错。

一种强制执行的方法是使用私有继承,但我猜您首先使用继承来保留std::queue 的大部分 API。

【讨论】:

  • 谢谢@Quimby,只是一个关于析构函数的问题,你提到STL容器没有虚拟析构函数,所以除非我重写基类的析构函数(这里是队列),没有问题这个实现对吗?
  • @Bad_Panda 扩展了我的答案。这几乎与覆盖无关。而且为了迂腐,析构函数不能被覆盖,删除给定的类总是调用基类的所有析构函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 2012-07-01
  • 2020-06-01
相关资源
最近更新 更多