   Static initialisation problem
  I have a class ResourceHolder which is basically a wrapper for an array. It has a static lookup method to find the name of a numbered resource, which I store in a std::vector<std::string> called 'names'. This vector is initialised in method called 'initialise', like so:void ResourceHolder::initialise () {  static bool initialised = false;  if (initialised) return;  initialised = true;  numResources = 9;  names.resize(numResources);}which I call from the ResourceHolder constructor:ResourceHolder::ResourceHolder () {  initialise();  theArray = new int[numResources];  clear();}Actually, I just realised that there's no particular reason for the numResources initialisation anymore, it could now just as well be a static const, but it's that way for historical reasons. Anyway. I have some of these ResourceHolders scattered about my code as static class variables. Now, when I try to call on the 'names' vector, the size of the vector is zero. But I can see the initialisation code being run and exiting with names.size() == 9, just as it should. When I do this:int main (int argc, char** argv) {  ResourceHolder b;  ResourceHolder::setName(0, "Labour");  std::cout << "Try 0" << ResourceHolder::getName(0) << std::endl;  return 0;}I get this for output:InitialisingExiting with 9Asked for name 0 of 9 0x804d2a4Try 0 Labourwhich is fine. But when I link to those pieces of my code that contain static ResourceHolders, I get insteadInitialisingExiting with 9test: ResourceHolder.cc:34: static int ResourceHolder::define(unsigned int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >): Assertion `names.size() > idx' failed.Observe that names has somehow been reset, so its size is now zero again. I conclude that this must be some issue with the static initialisation, but I don't understand how this can lead to a variable that's been very nicely set, thanks kindly, to be cleared again in this fashion! How can I avoid this resetting of the names vector? It's late, I hope this is clear.   
  Can you post the code for ResourceHolder::define, and the code that calls that function?   ;  is 'names' a global std::vector? i'm guessing that it is, in which case your static/global ResourceHolder objects' constructors are firing before the constructor of your global/static 'names' vector. Your ResourceHolder constructors resize it, but later, when the constructor for 'names' fires, it clears out the vector (causing a memory leak, as the default constructor for std::vector is likely just setting its members to 0/NULL).   ;  If your situation is as I described, then a quick and simple fix is the following.Replace yourstatic std::vector names;withstd::vector& getNames( ){   static std::vector names;   return names;}Now, the constructor for the names vector won't fire until the first time you call getNames( ), but it will be forced to fire before you actually access it and call resize on it.A perhaps better alternative in the long run is to try to avoid globals, though I'm not claiming that they're not appropriate sometimes.;  names is not global; it's a static member of ResourceHolder, like so:class ResourceHolder : public Holder {public:  ResourceHolder ();  ResourceHolder (ResourceHolder const* const c);  static unsigned int numResources;  static std::string getName (unsigned int idx);  static int define (unsigned int idx, std::string name);  bool equals (ResourceHolder const* const o) const;protected:  virtual void initialise ();  virtual unsigned int holderSize () {return numResources;}private:  // Static lookups for attributes of individual resources  static std::vector<std::string> names;};It's defined in the corresponding .cc, here:#include "ResourceHolder.hh"#include <assert.h>unsigned int  ResourceHolder::numResources = 0;std::vector<std::string> ResourceHolder::names;#include <iostream>ResourceHolder::ResourceHolder () {  initialise();  theArray = new int[numResources];  clear();}ResourceHolder::ResourceHolder (ResourceHolder const* const c) {  theArray = new int[numResources];  for (unsigned int i = 0; i < numResources; ++i) {    theArray = c->theArray;  }}bool ResourceHolder::equals (ResourceHolder const* const o) const {  for (unsigned int i = 0; i < numResources; ++i) {    if (theArray != o->theArray) return false;  }  return true;}int ResourceHolder::define (unsigned int idx, std::string name) {  assert(idx < numResources);  assert(names.size() > idx);  names[idx] = name;  return 1;}std::string ResourceHolder::getName (unsigned int idx) {  std::cout << "Asked for name " << idx << " of " << names.size() << " " << &names << std::endl;  return names[idx];}void ResourceHolder::initialise () {  static bool initialised = false;  if (initialised) return;  initialised = true;  numResources = 9;  std::cout << "Initialising" << std::endl;  names.resize(numResources);  std::cout << "Exiting with " << names.size() << std::endl;}And this is the calling code:#include "ResourceHolder.hh"//#include "Province.hh"#include <iostream>int main (int argc, char** argv) {  std::cout << "Here" << std::endl;  ResourceHolder b;  ResourceHolder::define(0, "Labour");  std::cout << "Try 3" << ResourceHolder::getName(0) << std::endl;  return 0;}That's all the calling code you need to get the crash - just uncomment the "#include Province.hh" and link in the corresponding object, which has a static ResourceHolder declared in it. If you don't do that, it doesn't crash. Obviously my actual program is a bit more complex, but I wanted to pare it down a bit for this debugging purpose. :)It seems to me that emeyex has put his finger on the problem even though names is not global; I don't see anything in his description of the event chain that wouldn't apply to a static class member. Right? So I'll try his solution. Thanks!   ;  Just saw the reply... FWIW, static member is for all intents and purposes the same as global (same linkage, same rules (or lack thereof) with regards to order of initialization). I tend to use the two terms interchangeably.   