0

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;
}
Claudio
  • 10,614
  • 4
  • 31
  • 71
  • As a sidenote, naming the member of all your classes as `data_` is confusing. How about more descriptive names like `dictionary` and `interfaces`? – eerorika Jun 09 '15 at 13:16
  • Initialization order of static objects across compilation units is indeed [undefined](http://stackoverflow.com/q/211237/4074081) – dewaffled Jun 09 '15 at 13:19

1 Answers1

1

It could be a problem related to the order of initialization of the objects.

A good guess. c is a static object of type shared<int>. The constructor ofshared<T> depends on the static object comm. c may very well be initialized before comm 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.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Thank you so much. Don't know why but I couldn't see it. Now I've succesfully solved it by transforming CommunicationHandler into a Singleton. – Claudio Jun 09 '15 at 13:46