在 std::vector 上调用 Push_back 时出现分段错误

问题描述 投票:0回答:1

下面我提供了我收到的错误的最小工作示例。在较高级别上,应用程序分段错误发生在我尝试将

push_back
Point
对象放入
vector
中定义的
DerivedEngine
的行。我已经包含了派生/CRTP 类结构,以防它很重要。

GDB 提供以下输出:

Program received signal SIGSEGV, Segmentation fault.
0x000055555555691d in __gnu_cxx::new_allocator<Point*>::construct<Point*, Point*> (this=0x7fffffffdde8, __p=0x0)
    at /usr/include/c++/9/ext/new_allocator.h:146
146     { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
(gdb) list
141 #if __cplusplus >= 201103L
142       template<typename _Up, typename... _Args>
143     void
144     construct(_Up* __p, _Args&&... __args)
145     noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
146     { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
147 
148       template<typename _Up>
149     void
150     destroy(_Up* __p)

工作代码示例如下:

#include <vector>
#include <unordered_map>
#include <iostream>

struct Data
{
     double x_ = 3.0;
     double y_ = 3.14;
};

template<typename Derived>
class AbstractEngine
{
public:
    AbstractEngine(int i)
    {
        add_data(i);
        auto data = view_data(i);
        std::cout << "Added data: " << data->x_ << " " << data << std::endl;
        on_init();
    }

    void on_init()
    {
      static_cast<Derived*>(this)->on_init();
    }

    void add_data(int i)
    {
        data_[i] = new Data(); 
    }

    Data* view_data(int i)
    {
        return data_[i];
    }

private:
    std::unordered_map<int, Data*> data_;
};

struct Point
{
    Point(double x) : x_(x) {} 
    double x_;
};

class DerivedEngine : public AbstractEngine<DerivedEngine>
{
public:
    DerivedEngine(int i) :
        AbstractEngine<DerivedEngine>(i) {}

    void on_init()
    {
        int i = 3;
        auto data = view_data(i);
        std::cout << "Viewed data: " << data->x_ << " " << data << std::endl;
    
        points_.push_back(new Point(3.14));
    }
private:
    std::vector<Point*> points_;
};


int main()
{
    DerivedEngine engine(3);
}

我尝试使用

unique_ptr
而不是原始指针进行重新表述,但无济于事。我怀疑这个问题与
vector
本身有关,而不是被推入其中的物体。

c++ segmentation-fault stdvector crtp
1个回答
0
投票

基类的构造函数正在调用方法

on_init

AbstractEngine(int i)
{
    add_data(i);
    auto data = view_data(i);
    std::cout << "Added data: " << data->x_ << " " << data << std::endl;
    on_init();
}

在该方法中,您关心强制转换为派生类

void on_init()
{
  static_cast<Derived*>(this)->on_init();
}

您仍在基类的构造函数中,因此派生类的生命周期尚未开始。

void on_init()
{
    int i = 3;
    auto data = view_data(i);
    std::cout << "Viewed data: " << data->x_ << " " << data << std::endl;

    points_.push_back(new Point(3.14));
}

在这里,您尝试对尚不存在的成员调用

push_back

© www.soinside.com 2019 - 2024. All rights reserved.