locked
VS2015 / issue with STL objects in constructor of static object RRS feed

  • Question

  • Hi,

    I have a class, which I want to use purely static.

    This class has stl member elements e.g. <map>

    This members needs to be initialized at startup.

    So my idea is, that I would do this inside the constructor.

    This works, as long as I create instances from this class dynamically.

    When the class has only static member functions, I do not need dynamically created instances. But then the constructor of the class is never called. To solve this, I create a static instance of the class:

    MyStaticClass  _dummy;  

    This causes the constructor to be called at startup, which actually works fine.

    But the application crashes, when inside this constructor the map object is accessed.

    Seems that on Application startup the constructors of my statically defined objects are called before stl is available.

    Is that right? Is there any solution? Or do I need to rethink about usage of stl ??

    Many Thanks

    Richard

      

    Thursday, November 16, 2017 8:52 AM

Answers

  • Many thanks for the very fast reply!!

    In the meantime I've found the problem. Actually it was my fault!

    Let's explain:

    //Header File:
    //------------------------------------------
    class CGenCodec
    {
    public:
    	CGenCodec();
    	~CGenCodec(void);
    
    }
    
    //Source File:
    //-----------------------------------------
    
    
    CGenCodec _GenCodec;		// static object would cause the constructor to be called
    
    typedef struct
    {
    	WORD wCode[2];
    }tTabMC5;
    typedef std::map<std::string, tTabMC5> tTABMNEMO;
    tTABMNEMO TabMnemo;
    
    CGenCodec::CGenCodec()
    {
    ...
       TabMnemo.clear(); // <-- crash in case of static instance
    
    ...
    }
    
    

    This code is crashing in the constructor at first access to TabMnemo.

    The reason is, that this map object is defined statically outside of the class and is defined after static class instance. So the map object is not initialized in this moment.

    When I change the order of the definitions or when I would move the definition of the map object inside the class, everything works fine.

    I do not remember exactly, why I have made like this. Maybe this table was a simple array before with huge size ( 64000 elements) and I got compilation errors because of the size, when this array was inside the class.

    • Proposed as answer by Baron Bi Monday, November 20, 2017 8:44 AM
    • Marked as answer by itr_rrauch Monday, November 20, 2017 6:58 PM
    Thursday, November 16, 2017 12:26 PM

All replies

  • Unfortunately you haven't given much information on exactly what you are doing. You see, the simple:

    #include <map>
    
    struct myclass
    {
    	std::map<int, std::wstring> mymap;
    };
    
    myclass _dummy;
    
    int wmain()
    {
    	return 0;
    }

    Works without any issues, so it can't be because the STL hasn't loaded. In the case of using the DLL version of the STL (/MD compiler option) then any initialisation is done during the process load, when msvcp140.dll is loaded into the process. When you are using the static version of the STL (/MT) the library is initialised during the initterm call in mainCRTStartup, and the compiler prioritises the calls.

    If you are splitting this over multiple object files, so you are putting the class in one source file and things that use it in another source file as static objects, then this could be the problem. The order in which static objects are initialised is not defined.

    But you will have to provide more information, preferably a sample showing what you are doing (cut down and still exhibits the problem from your real life program).


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Thursday, November 16, 2017 10:04 AM
  • Many thanks for the very fast reply!!

    In the meantime I've found the problem. Actually it was my fault!

    Let's explain:

    //Header File:
    //------------------------------------------
    class CGenCodec
    {
    public:
    	CGenCodec();
    	~CGenCodec(void);
    
    }
    
    //Source File:
    //-----------------------------------------
    
    
    CGenCodec _GenCodec;		// static object would cause the constructor to be called
    
    typedef struct
    {
    	WORD wCode[2];
    }tTabMC5;
    typedef std::map<std::string, tTabMC5> tTABMNEMO;
    tTABMNEMO TabMnemo;
    
    CGenCodec::CGenCodec()
    {
    ...
       TabMnemo.clear(); // <-- crash in case of static instance
    
    ...
    }
    
    

    This code is crashing in the constructor at first access to TabMnemo.

    The reason is, that this map object is defined statically outside of the class and is defined after static class instance. So the map object is not initialized in this moment.

    When I change the order of the definitions or when I would move the definition of the map object inside the class, everything works fine.

    I do not remember exactly, why I have made like this. Maybe this table was a simple array before with huge size ( 64000 elements) and I got compilation errors because of the size, when this array was inside the class.

    • Proposed as answer by Baron Bi Monday, November 20, 2017 8:44 AM
    • Marked as answer by itr_rrauch Monday, November 20, 2017 6:58 PM
    Thursday, November 16, 2017 12:26 PM
  • Yeah, this kind of thing is easy enough to do, and I'm glad you found where the problem was.

    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Thursday, November 16, 2017 12:36 PM