Static member use before its initialization


A

Alex Vinokur

Class Bar in a program below contains two static members: v1 and v2 of
class Foo.
v1 is initialized before creating an instance of Bar, v2 v1 is
initialized after that instance.
No Foo-constuctor for v2 was called before line
"Bar b".
However, (temporary ?) instance for v2 was created in Bar::Bar(). How
was it created: without calling constructor?


------- foo.cpp -------
#include <iostream>
#include <vector>
using namespace std;

struct Foo : public vector<int>
{
Foo() { cout << "Foo::Ctor-0" << endl;}
Foo(size_t n) : vector<int> (n) { cout << "Foo::Ctor-1: n = " << n <<
endl;;}
};

struct Bar
{
static Foo v1;
static Foo v2;
static void Show(const char* const msg);
Bar();
};

Bar::Bar()
{
Show ("[Bar()-A]");

v1.push_back(0);
v2.push_back(0);

Show ("[Bar()-B]");
}

void Bar::Show(const char* const msg)
{
cout << msg << ": v1.size()" << v1.size() << ", v2.size() = " <<
v2.size() << endl;
}

Foo Bar::v1(100);
Bar b;
Foo Bar::v2(200);

int main()
{
Bar::Show ("[main] ");
return 0;
}
-----------------------



------- Run -------
Foo::Ctor-1: n = 100
[Bar()-A]: v1.size()100, v2.size() = 0
[Bar()-B]: v1.size()101, v2.size() = 1
Foo::Ctor-1: n = 200
[main] : v1.size()101, v2.size() = 200
-------------------




Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn
 
Ad

Advertisements

T

Tom Widmer

Alex said:
Class Bar in a program below contains two static members: v1 and v2 of
class Foo.
v1 is initialized before creating an instance of Bar, v2 v1 is
initialized after that instance.
No Foo-constuctor for v2 was called before line
"Bar b".
However, (temporary ?) instance for v2 was created in Bar::Bar().

No, you just accessed the uninitialized storage for v2.

How
was it created: without calling constructor?

Your program has undefined behaviour since you use v2 before it has been
initialized. As for an explanation of the exact undefined behaviour you
are seeing, global objects have their memory zeroed before any other
initialization occurs. It just so happens that all-zeroed was valid for
your Foo object v2, so when v2.push_back(0) is called, it thinks it is
being called on an empty vector and the code operates accordingly.
However, your v2 constructor then runs so you end up leaking the memory
you just allocated.

Tom
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Top