By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,129 Members | 1,331 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,129 IT Pros & Developers. It's quick & easy.

static initialization access violation error

P: n/a
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

Jul 23 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
marvind wrote:
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


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".
Jul 23 '05 #2

P: n/a
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?

Jul 23 '05 #3

P: n/a

"marvind" <ma********@yahoo.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
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?

What's "Root()"???
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

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

Jul 23 '05 #4

P: n/a
marvind wrote:
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?


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.
Jul 23 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.