1

I have a program with a main function that simply prints a string. When I run this program it crashed without output in the console. I found out the problem happens when I insert an element into the map of OperatorCore (symbolMap).

This is the minimal code:

//Binary.hpp
class Binary final : public OperatorCore, public StaticPool<Binary> {
public:
    Binary(int ID, std::string name)
        : OperatorCore(name), StaticPool<Binary>(ID) {
    }
    ~Binary() {}
};
//Binary.cpp
template<>
const Binary StaticPool<Binary>::pool[] = {
    Binary(0, "a string value")//without this line of code, it prints works
};

//OperatorCore.hpp
class OperatorCore {
public:
    static std::map<std::string, OperatorCore*> symbolMap;
    const std::string name;
    OperatorCore (std::string name);
    virtual ~OperatorCore () {}
};
//OperatorCore.cpp
std::map<std::string, OperatorCore*> OperatorCore::symbolMap{};
OperatorCore::OperatorCore(std::string name) : name(name) {
    symbolMap.insert({name, this});
}


//StaticPool
template<typename T, typename TKey = int>
class StaticPool {
public:
    const TKey ID;
    static const T pool[];
    StaticPool(TKey ID) : ID(ID) {}
    virtual ~StaticPool() {}
};

The problem does not occur if I delete one of the highlighted lines. Does this design cause a memory corruption?

EDIT: The initialization of OperatorCore::symbolMap is in the same file where is also the implementation of OperatorCore constructor.

0

2 Answers 2

1

I suspect you have an order-of-initialization problem. In other words, your program tries to initialize pool before symbolMap, and the constructor of the Binary object calls the base constructor, which tries to use symbolMap, which hasn't been constructed yet.

There are a number of solutions for this. Your best bet is probably to turn the symbolMap static member into a static variable inside a special getter function:

class OperatorCore {
public:
    static std::map<std::string, OperatorCore*>& symbolMap() {
        static std::map<std::string, OperatorCore*> instance;
        return instance;
    }
};
Sign up to request clarification or add additional context in comments.

2 Comments

The initialization of symbolMap and the implementation of the OperatorCore's constructor are ine same .cpp file.
The code for OperatorCore's constructor is irrelevant. What matters is that the definitions of OperatorCore::symbolMap and StaticPool<Binary>::pool are in different files.
1

You have a case of static initialization order fiasco. Meaning that your statics might be constructed in the wrong order. I do not know if initializing the static objects in the same file in the correct order works. But otherwise you should delay the initialization of the pool which depends on the map. Maybe write a function to initialize the pool and call it at the start of your main.

7 Comments

Yes, I edited the question. The initialization is in the same file cpp file where is also che OperatorCore constructor body. std::map<std::string, OperatorCore*> OperatorCore::symbolMap{};
@biowep: please correct the constructor name as well, and show the initialization, so we can see the order. Another idea would be to initialize the pool from a function, but that is if the before part fails. Maybe supply a complete MWE (with a main function)
@biowep: by the way it looks like you are using cpp11, you should be able to inline initialize the static members.
if I do so, I get an error: in-class initialization of static data member 'std::map<std::basic_string<char>, OperatorCore*> OperatorCore::symbolMap' of incomplete type
@biowep: class x { static templateType<x*> y={} } has no other choice than giving you the above error unless you give a forward declaration. But your problem is elsewhere, you have a static initialization order fiasco.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.