试图访问对象成员时出现segfault

Seg fault trying to access an object member

本文关键字:segfault 成员 访问 对象      更新时间:2023-10-16

为了遵循本文http://goo.gl/DvglYv中的示例,我设计了以下类:

Bridge.h:

class Bridge {
public:
    IfFrameSender *pFrmSender;
    std::string senderName;
    ...
    Bridge(cfg_settings cfg_sett);
    void saveFrame(cv::Mat &cvFrm, uint XOff, uint YOff);
    ...
}

pFrmSender是一个指向虚拟类IfFrameSender的指针。

在Bridge.cpp中,我定义了构造函数:
Bridge::Bridge(cfg_settings cfg_sett)
{
    ...
    /* Instantiates a sender_by_socket object using a factory */
    IfFrameSender *pFrmSender = FrameSenderFactory::Get()->CreateFrameSender("FrameSenderBySocket"); 
    ...
}

和方法:

void Bridge::saveFrame(cv::Mat &cvFrm, uint XOff, uint YOff)
{
    ...
    pFrmSender->sendFrame(...);
    ...
}

嗯,当我试图调用pFrmSender时,我得到一个segfault。我做了一点调试,我发现在Bridge::saveFrame方法中,成员有一个不正确的内存地址(CCCCCCCC),而在构造函数中,它是正确的,我已经打印了它的内存地址,它似乎是一致的。

我已经在头文件中声明了这个成员,所以我认为它可以被Bridge类的任何方法看到。我哪里错了?

问题是:

Bridge::Bridge(cfg_settings cfg_sett)
{
  /* Following is a temporary variable, which is destroyed after this ctor returns */
  IfFrameSender *pFrmSender = FrameSenderFactory::Get()->CreateFrameSender("FrameSenderBySocket"); 
}

在构造函数中创建了一个新的(临时的)IfFrameSender *,一旦构造函数返回,它将被销毁。相反,初始化声明为类成员的那个:

Bridge::Bridge(cfg_settings cfg_sett)
{
  this->pFrmSender = FrameSenderFactory::Get()->CreateFrameSender("FrameSenderBySocket"); 
}

在使用指针时检查null也是更好的做法:

void Bridge::saveFrame(cv::Mat &cvFrm, uint XOff, uint YOff){
   if(pFrmSender!=nullptr) 
      pFrmSender->sendFrame(...);
 }

虽然,我猜在这种情况下,如果pFrmSender不能构造,那么Bridge::Bridge()可能会抛出异常,如果创建自己是没有意义的。

试试这个:

Bridge::Bridge(cfg_settings cfg_sett) :
    pFrmSender(FrameSenderFactory::Get()->CreateFrameSender("FrameSenderBySocket"))
{
}

这样你实际上是在初始化你的类成员。