【问题标题】:SIGSEGV with std::map of pointers to template objects带有指向模板对象的指针的 std::map 的 SIGSEGV
【发布时间】:2015-06-09 12:57:48
【问题描述】:

我需要保留一个 std::map 指向模板化对象的指针。 为了摆脱模板,我使用了一个通用的非模板基类。

运行代码时,我收到一个 SIGSEGV 信号。 调试显示问题出在语句

data_[id] = s;

这可能是与对象的初始化顺序有关的问题。

代码如下所示:

文件 shared_iface.h:

class shared_iface {
    unsigned long int counter_;
};

文件 shared.h:

extern CommunicationHandler comm;

template <typename T>
class shared: private shared_iface {
public:
    shared(): data_(nullptr), id_(0) {
        comm.add(id_, this);
    }
private:
    T* data_;
    unsigned long int id_;
};

文件communication_handler.h:

class CommunicationHandler {
public:
    inline void add(unsigned long int id, shared_iface* s) {
        data_.add(id, s);
    }
private:
    Dictionary data_;
};

文件communication_handler.cpp:

CommunicationHandler comm;

文件字典.h:

class Dictionary {
public:
    Dictionary() {
        data_.clear();
    }
    void add(unsigned long int id, shared_iface* s) {
        data_[id] = s;
    }
private:
    std::map<unsigned long int, shared_iface*> data_;
};

文件 main.cpp:

#include "shared.hpp"

shared<int> c;

int main ()
{
    return 1;
}

【问题讨论】:

  • 作为旁注,将所有类的成员命名为 data_ 会造成混淆。像dictionaryinterfaces 这样更具描述性的名称怎么样?
  • 静态对象跨编译单元的初始化顺序确实是undefined

标签: c++ templates inheritance g++ stdmap


【解决方案1】:

这可能是与对象的初始化顺序有关的问题。

一个很好的猜测。 cshared&lt;int&gt; 类型的静态对象。 shared&lt;T&gt;的构造函数依赖于静态对象commc 很可能在 comm 之前初始化,你会得到未定义的行为。 comm 本来可以先初始化,你很幸运你的代码没有工作。

这被称为static initialization order fiasco。避免惨败的常用方法是Construct On First Use Idiom,但一般来说,避免依赖于其他静态对象的静态对象。

【讨论】:

  • 非常感谢。不知道为什么,但我看不到它。现在我通过将 CommunicationHandler 转换为 Singleton 成功解决了它。
猜你喜欢
  • 2012-04-19
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多