1

Please help,

The problem: core dumps in following code:

I have an abstract class SomeOtherClass, and have derived from it SomeOtherClassImpl.

Here is the code which causes the trouble:

class MyClass
{

public:

  void someFunction()
  {
    myVector().push_back(someOtherClassDefault());
  }

private:

  static std::vector<SomeOtherClass const *> & myVector()
  {
    static std::vector<SomeOtherClass const *> theVector;
    return theVector;
  }

  static SomeOtherClass const * someOtherClassDefault()
  {
    static SomeOtherClassImpl theDefault;
    return &theDefault;
  }

};

I have some static variables of MyClass type in other translation units.

The problem is weird as segmentation fault occures when program exits. Of course theDefault can be deallocated before theVector, but what's the difference? Both deallocated when main is already done.

You help will be much appreciated.

Andy Finkenstadt
  • 3,547
  • 1
  • 21
  • 25
  • 3
    I can't see anything obviously wrong with the above code, so you probably need to provide a cut-down version of `SomeOtherClassImpl`. If you run your application in a debugger, what is the backtrace when the seg-fault occurs? – Oliver Charlesworth Apr 28 '11 at 16:27
  • 1
    And you think that what happens after "main is already done" is none of your business? – Nikolai Fetissov Apr 28 '11 at 16:35
  • Nikolai, thank you for motivating comment :) but you are right, it is my business, and it's actually my mistake. – Dmitry Statnikov Apr 29 '11 at 13:43

1 Answers1

5

You are most probably hitting the static initialization fiasco, just on the opposite end. Basically, the order of destruction of objects of static duration is the reverse order of creation of the same. So if you have:

void foo() {
   static type a;
}
void bar() {
   static type b;
}
int main() {
   foo();
   bar();
}

The construction will create first a, and then b, when main completes, it will destroy b then a. If you switch the order of the calls in main, then the order will be inverted. You have to be aware when dealing with variables of static duration on dependencies for this particular reason.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • 1
    Right, but can you see in the OP's code why the order matters at all? I can't. – C. K. Young Apr 28 '11 at 16:43
  • I can't either. There is probably some other code accessing one of these objects after they have been destroyed. – hammar Apr 28 '11 at 17:45
  • I cannot see it in the code, but from the description this seems to be the issue. Most probably this is a simplified version, where the vector replaces some other class that actually access the argument on destruction. Say a class that contains the vector and that on destruction is iterates over the elements and calls a member function. In that case, the class would be created before the elements, and during destruction of that class, the iteration would touch destroyed objects. – David Rodríguez - dribeas Apr 28 '11 at 18:47
  • David and hammar are right. I should add a destructor code: `MyClass::~MyClass() {size_t i; ...; myVector()[i] = NULL; ...}`. And of course `myVector()[i] = NULL;` is a crime. – Dmitry Statnikov Apr 29 '11 at 13:37