static initialization access violation error

Discussion in 'C++' started by marvind, Jul 12, 2005.

  1. marvind

    marvind Guest

    I think I am running into the static initialization problem but I do
    not understand why.

    I am trying to parse a configuration file. To make this parser generic
    I register callbacks for various section keywords in the configuration
    file. I want to share this map of callbacks across multiple instances
    of the config file (for example, when I merge two files). Whenever I
    introduce a new section in the configuration file, I define a new class
    for this section and also register the new callback for this section
    with a new keyword.

    I get an access violation exception when I step through this code and I
    see the callback map Root() is uninitialized. Since I am trying to
    populate the callback map only after constructing an instance of the
    configuration class, why is the static callback map still
    uninitialized?

    Below is the basic code structure:

    -- In CConfig.h
    class CConfig
    {
    public:
    ...
    // Note that Register is not a static function
    bool Register(const std::string& skey, CallbackFn callback);
    private:
    // want to share this map across all instances
    static std::map<std::string, CallbackFn> s_callbacks;
    };


    -- In CCMA.h
    class CCMA : public CSection
    {
    ...
    };

    -- In CCMA.cpp
    // anonymous namespace
    namespace
    {
    // ReadCMA -> new CCMA and then read relevant tags from config file
    bool bRegisterCMA = G_CONFIG.Register("CMA_START", ReadCMA);
    };

    G_CONFIG returns either existing global pointer to CConfig after
    creating a new CConfig object if necessary simulating singleton
    behavior. However, we sometimes need more than one instance of CConfig
    for example to merge entries from 2 different configuration files and
    so we access these without using G_CONFIG (I still want to share the
    callback map).

    Thanks
     
    marvind, Jul 12, 2005
    #1
    1. Advertisements

  2. marvind

    Paul Groke Guest

    You need to make sure that "s_callbacks" is initialized before
    "bRegisterCMA" is. One way to do so would be to grab a proper
    Sincleton implementation, and make "s_callbacks" a singleto too.
    The simple solution for single-threaded programs is to put all your
    static data in functions that return references to the data. That way
    you make sure that they are constructed in the right order.

    And: you get the problem because "s_callbacks" is not initialized with
    the first instance of the class, but along with all other static data.
    Nonconst static members are just "globals in a namespace".
     
    Paul Groke, Jul 13, 2005
    #2
    1. Advertisements

  3. marvind

    marvind Guest

    Thank you for your response.

    I wrapped the callback map as you suggested:
    stlCallbackMap& CallbackMap()
    {
    static stlCallbackMap callbackMap;
    return callbackMap;
    }

    That "seems" to work. My mistake was that I thought that static data
    members of a class are initialized before the first instance of the
    class is constructed, instead of the runtime treating them as just
    globals in a namespace.

    Are there good "free" tools that I can use to find out if there are
    such errors in the code since these errors depend on how the files are
    compiled?
     
    marvind, Jul 13, 2005
    #3
  4. marvind

    Howard Guest

    What's "Root()"???

    You're assuming that s_callbacks is initialized when the first instance of
    the class is created. That's not the case. You need to initialize it
    yourself somewhere. That can be done in the manner of a Singleton (inside
    an accessor function), or at the global level (outside the class in your
    implementation file).

    -Howard
     
    Howard, Jul 13, 2005
    #4
  5. marvind

    Paul Groke Guest

    If it depends on how it's compiled, then it's an error - whether it
    shows or not.
    As for tools: asserts, logs, traces. Other than that I don't know
    free tools - though they might probably exist. In my company we
    use MSVC7.1 which happens to have an excellent debugger, and for
    real tough cases we use Bounds-Checker and/or VTune (profiling).

    You might ask in a group/forum specific to whatever OS/compiler
    you are using.
     
    Paul Groke, Jul 14, 2005
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.