View Full Version : C++ global class instance's static member not same between functions
SGFzc2U=
February 29th, 2012, 06:05 PM
entity.C
std::vector<int> entity::vec;
entity::entity(){
vec.push_back(1);
std::cout<<"From constructor:"<<vec.size()<<std::endl;
}
void entity::showAmount(){
std::cout<<"From showAmount: "<<vec.size()<<std::endl;
}
bug.C
entity a,b;
int main(){
b.showAmount();
return 0;
}
Output:
From constructor:1
From constructor:2
From showAmount: 0
:confused::confused::confused:
When the entity declarations are local in main(), everything works as expected, with output:
From constructor:1
From constructor:2
From showAmount: 2
dwhitney67
February 29th, 2012, 10:26 PM
Surely there is more to your code than you have shown. Please post all of it, not just a snip.
--------------------------------
Edit:
The problem you are experiencing is probably related to a race condition between initializing the static member of the class and the construction of the global variables, which btw, should be avoided! On my system, I experimented with some code that mimics what you have above, and the application crashed with a Segmentation Fault. If I place the declaration of entity objects 'a' and 'b' within the main() function, then all works well.
SGFzc2U=
March 1st, 2012, 08:36 AM
That's all the code for recreating the bug minus the #includes and the class definition. Since the full source is >500 rows, it would fill the whole page :)
I found out, that the problem only occurs when the static member is a vector. When it's int, it works as expected. Here's the new source:
entity.C
std::vector<int> entity::vec;
int entity::amount=0;
entity::entity(){
vec.push_back(1);
amount++;
std::cout<<"From constructor: vec:"<<vec.size()<<" amount: "<<amount<<std::endl;
}
void entity::showAmount(){
std::cout<<"From showAmount: vec:"<<vec.size()<<" amount: "<<amount<<std::endl;
}
bug.C is the exact same as last time.
Out:
From constructor: vec:1 amount: 1
From constructor: vec:2 amount: 2
From showAmount: vec:0 amount: 2
Maybe I'll just substitute the vector with a pointer, and not fight with this anymore.
Npl
March 1st, 2012, 08:16 PM
what likely happens is that the constructors are called in this sequence:
a.entity(); // accesses uninitialized entity::vec -> size = 1
b.entity(); // accesses uninitialized entity::vec -> size = 2
entity::vec.vector(); // initializes entity::vec -> size = 0
then later entity::showAmount() is called.
lesson learned: never depend on initialization order. it should work if you move "std::vector<int> entity::vec;" into bug.c, before "entity a,b;" but thats ugly since you might need an entity instance elsewhere.
similary moving entity a,c into main works because then its guaranteed that entity::vec already got initialized.
either rework your object hierarchy or use the singleton pattern.
Powered by vBulletin® Version 4.2.2 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.