【问题标题】:Segfault when trying to access function of member in a library尝试访问库中成员的功能时出现段错误
【发布时间】:2014-05-31 11:39:12
【问题描述】:

我有一个通过谷歌测试套件彻底测试过的库。我试图保持它“pimpl”干净,但我遇到了一个我无法弄清楚的段错误。

相关代码:

Interface.h:

class Interface{
public: 
Interface();
void Function(const int argument);

private:
std::unique_ptr<Implementation> Implement;    
std::unique_ptr<DependencyInjection> Injection1, Injection2;    
};

接口.cpp:

Interface::Interface()
: Injection1(new DependencyInjection()),
Injection2(new DependencyInjection()),
Implement(new Implementation(*Injection1, *Injection2)) {}

void Interface::Function(const int argument){ Implement->Function(argument); }

实施.h:

class Implementation{
public: 
Implementation(AbstractInjection &injection1, AbstractInjection &injection2);
void Function(const int argument);
private:
AbstractInjection Injection1, Injection2;
};

实施.cpp

Implementation::Implementation(AbstractInjection &injection1, AbstractInjection &injection2)
: Injection1(injection1),
Injection2(injection2) {}

void Implementation::Function(const int argument){
injection1.Function(argument); } // code from here out is all well tested and works 

因此,当我创建接口并调用 Interface.Function() 时,代码会在尝试评估 Implementation.Function() 时出现段错误。我已经通过我能想到的一切运行 gdb,所有指针都是非空的。

如果我只是创建一个看起来像这样的测试

std::unique_ptr<DependencyInjection1> injection1(new DependencyInjection());
std::unique_ptr<DependencyInjection2> injection2(new DependencyInjection());
std::unique_ptr<Implementation> implement(new Implementation(*injection1, *injection2));
implement->Function(0);

代码工作正常,没有段错误

但如果我创建一个类似的测试

Interface iface;
iface.Function(0);

它会出现段错误。

我对整个 unique_ptr 事情并不陌生,但我怀疑这不是更大的问题。这可能是一个红鲱鱼,我不知道。

【问题讨论】:

    标签: c++ segmentation-fault unique-ptr pimpl-idiom


    【解决方案1】:

    您的成员字段顺序错误,它们按照在类中声明的顺序进行初始化。所以implementinjections 之前被初始化。使用-Werror=reorder 获取编译器错误(对于 GCC 和可能的 CLang)

    【讨论】:

      【解决方案2】:

      问题实际上应该作为警告弹出。

      初始化器是按照它们在类定义中出现的顺序完成的,而不是它们在构造函数中出现的顺序!

      切换到:

      class Interface{
      public: 
      Interface();
      void Function(const int argument);
      
      private:
      std::unique_ptr<DependencyInjection> Injection1, Injection2;
      std::unique_ptr<Implementation> Implement;
      
      };
      

      来自这里:C++: Initialization Order of Class Data Members,这是“C++ 标准的 12.6.2”

      【讨论】:

      • -编辑:不,毕竟我把它们弄错了。对不起,那是对的!非常感谢!测试通过。 (上一条评论):对不起,我在代码中按正确的顺序排列了它们,但我在帖子中没有按正确的顺序编写它们。
      • @Alex 我想说你的接口可能不应该拥有 Injection1 和 Injection2,你制作了 Injection 类的两个副本。此外,在实现调用中分配给“AbstractInjection”实例时,您将获得切片。
      • 是的,当我把它复制到这里时,它更像是抽象的产物。它真的更像是 A 类; B类:A类;和 X 类、Y 类:B 类、Z 类:A 类。然后实现有一个构造函数(B,B,A)和接口注入(X,Y,Z)。在测试的情况下是(MockX、MockY、MockZ)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多