I need to keep a std::map of pointers to templated objects. To get rid of templates, I use a common untemplated base class.
When running the code, I get a SIGSEGV signal. Debugging shows that the problem arises with statement
data_[id] = s;
It could be a problem related to the order of initialization of the objects.
The code looks like this:
File shared_iface.h:
class shared_iface {
unsigned long int counter_;
};
File 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_;
};
File communication_handler.h:
class CommunicationHandler {
public:
inline void add(unsigned long int id, shared_iface* s) {
data_.add(id, s);
}
private:
Dictionary data_;
};
File communication_handler.cpp:
CommunicationHandler comm;
File 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_;
};
File main.cpp:
#include "shared.hpp"
shared<int> c;
int main ()
{
return 1;
}
A good guess.
c
is a static object of typeshared<int>
. The constructor ofshared<T>
depends on the static objectcomm
.c
may very well be initialized beforecomm
and you'll get undefined behaviour.comm
could have been initialized first, you're lucky that your code didn't work.This is known as static initialization order fiasco. The usual way to avoid the fiasco is Construct On First Use Idiom but in general, avoid static objects that depend on other static objects.