2

I have a global variable inside an anonymous namespace.

namespace {
std::unordered_map<std::string, std::string> m;
}


A::A() { m.insert(make_pair("1", "2")); } // crasches
void A::insert() { m.insert(make_pair("1", "2")); } // ok

If try to use the map inside the constructor I get Access violation reading location. But if I use it after A has been initialized it works.
Is this behavior correct?

4
  • Do you have a static member A? Commented Aug 13, 2012 at 13:30
  • 1
    If there is global A instance defined in another cpp file, creation order of this instance and m is undefined. Commented Aug 13, 2012 at 13:31
  • How you are trying to use the map ? Commented Aug 13, 2012 at 13:32
  • Are you constructing the A before main() is entered? i.e. is there another global variable of type 'A`? Commented Aug 13, 2012 at 13:42

2 Answers 2

8

What is the scope of the A object whose constructor invocation is causing the crash?

There are no guarantees as to the order that static initializers are executed, so that if your A object is also a global or static (as m is), it's quite possible that m does not exist yet in terms of being a validly constructed object, which would mean that your call to std::unordered_map::insert() would be invoked on uninitialized memory, thus leading to your crash.

A solution is to make sure that all of your A instances that depend on m are constructed explicitly by you and not statically/globally (or as the commenter added, if they are in the same TU, to order them properly), or to change the structure of A such that you can call a function on an instance later in order to do the insert. Whether or not this is a valid solution depends more on the overarching usage of A.

Sign up to request clarification or add additional context in comments.

3 Comments

One correction: there is no such guarantee across translation units. Within one translation unit, they are initialized in the order of declaration.
And one addition: the best thing to do is avoid dependencies between static objects initialization; but if it can't be done -- use a create-on-access singleton instead of plain static variable.
This is unlikely to be the problem if the user is correct in their description (but I think we are missing a piece and you have guessed that). Because it is in an anonymous namespace it is already in the same translation unit (as anonymous namespace objects are limited in that way). The way the code is shown above shows m to be declared before any A (though there is a lot left to the imagination). So the order of initialization should not be an issue (if it is a simple re-ordering of globals should solve the problem).
2

You are probably creating a class of type A in a static context somewhere in your application, ie before your main() function is executed, and therefore before m has been initialized.

Comments

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.