首页 > 解决方案 > 为什么调用模板类函数时会出现 SEGFAULT?

问题描述

注意:他的问题与关于 GpuLaserPlugin 对象破坏的 Gazebo 问题有关 - 对于原始问题,请参见此处,其中也有重现问题的说明)

我在尝试销毁Connection对象时遇到了段错误问题:

class GZ_COMMON_VISIBLE Connection
{
  public: Connection(Event *_e, const int _i);
  public: ~Connection();
  // Get the id of this connection.
  // The id of this connection.
  public: int Id() const;
  // The event for this connection
  private: Event *event = nullptr;
  private: int id = -1;
  private: common::Time creationTime;
  public: template<typename T> friend class EventT;
};

析构函数Disconnect()EventT模板类调用,该类的子Event类:

class GZ_COMMON_VISIBLE Event
{
  public: Event();
  public: virtual ~Event();
  public: virtual void Disconnect(int _id) = 0;
  public: bool Signaled() const;
  public: void SetSignaled(const bool _sig);
  private: bool signaled;
};

...

template<typename T>
class EventT : public Event
{
  public: EventT();
  public: virtual ~EventT();
  public: ConnectionPtr Connect(const std::function<T> &_subscriber);
  public: virtual void Disconnect(int _id);

...

}

...

void EventT<T>::Disconnect(int _id)
{
  printf("Start disconnect \n");                                //for debug

  // Find the connection
  auto const &it = this->connections.find(_id);

  if (it != this->connections.end())
  {
    it->second->on = false;
    this->connectionsToRemove.push_back(it);
  }
  printf("End disconnect \n");                                  //for debug
}

Connection析构函数:

Connection::~Connection()
{
  gzwarn << "Start destructor \n";                                  //for debug

  if (this->event && this->id >= 0)
  {
    this->event->SetSignaled(true);
    bool eventBool = this->event->Signaled();                       //for debug
    std::cout << "ID value is " << this->id << std::endl;           //for debug
    std::cout << "Event bool value is " << eventBool << std::endl;  //for debug
    std::cout << typeid(this->event).name() << std::endl;           //for debug
    this->event->Disconnect(this->id);
    this->id = -1;
    this->event = nullptr;
  }
  gzwarn << "End destructor \n";                                    //for debug
}

不幸的是,当Disconnect()被称为段错误时(完整的回溯可以在这里找到)

我通过在函数调用之前打印它们的值和事件类型来检查成员变量是否仍然id存在:event

[Wrn] [Event.cc:60] Start destructor 
ID value is 0
Event bool value is 1
PN6gazebo5event5EventE

Thread 1 "gzserver" received signal SIGSEGV, Segmentation fault.
0x000055555719fd20 in ?? ()

对我来说似乎很奇怪的是 SEGFAULT 发生在Disconnect()函数调用之后实际进入它之前的某个地方(因为Start disconnect从未打印过调试语句),这表明问题在于idor event,尽管根据输出这些应该存在。

谁能解释一下为什么调用这个函数会导致 SEGFAULT?

标签: c++templatessegmentation-fault

解决方案


推荐阅读