具有 std::map 个指向模板对象的指针的 SIGSEGV
SIGSEGV with std::map of pointers to template objects
我需要保留 std::map 个指向模板化对象的指针。
为了摆脱模板,我使用了一个通用的非模板化基础 class.
当 运行 代码时,我得到一个 SIGSEGV 信号。
调试发现问题出在statement
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;
文件dictionary.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;
}
It could be a problem related to the order of initialization of the objects.
猜对了。 c
是类型 shared<int>
的静态对象。 shared<T>
的构造函数依赖于静态对象comm
。 c
很可能在 comm
之前被初始化,你会得到未定义的行为。 comm
本来可以先初始化的,幸好你的代码没用。
这称为 static initialization order fiasco. The usual way to avoid the fiasco is Construct On First Use Idiom,但一般来说,避免依赖于其他静态对象的静态对象。
我需要保留 std::map 个指向模板化对象的指针。 为了摆脱模板,我使用了一个通用的非模板化基础 class.
当 运行 代码时,我得到一个 SIGSEGV 信号。 调试发现问题出在statement
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;
文件dictionary.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;
}
It could be a problem related to the order of initialization of the objects.
猜对了。 c
是类型 shared<int>
的静态对象。 shared<T>
的构造函数依赖于静态对象comm
。 c
很可能在 comm
之前被初始化,你会得到未定义的行为。 comm
本来可以先初始化的,幸好你的代码没用。
这称为 static initialization order fiasco. The usual way to avoid the fiasco is Construct On First Use Idiom,但一般来说,避免依赖于其他静态对象的静态对象。