Initialization of member: bug in GCC or my thinkin

2019-05-04 00:47发布

问题:

I've got an enum type defined in the private section of my class. I have a member of this type defined as well. When I try to initialize this member in the constructor body, I get memory corruption problems at run-time. When I initialize it through an initialization list in the same constructor instead, I do not get memory corruption problems. Am I doing something wrong?

I'll simplify the code, and if it is a GCC bug I'm sure that it's a combination of the specific classes I'm combining/inheriting/etc., but I promise that this captures the essence of the problem. Nothing uses this member variable before it is initialized, and nothing uses the newly created object until after it is fully constructed. The initialization of this member is indeed the first thing I do in the body, and when the memory corruption happens, valgrind says it is on the line where I initialize the variable. Valgrind says that it is an invalid write of size 4.

Pertinent header code:


private:  
  enum StateOption{original = 0, blindside};    
  StateOption currentState;

pertinent .cpp code (causes memory corruption and crash):


MyClass::MyClass(AClass* classPtr) : 
  BaseClass(std::string("some_setting"),classPtr)
{
  currentState = original;
  ...
}

pertinent .cpp code (does not cause memory corruption and crash):


MyClass::MyClass(AClass* classPtr) : 
  BaseClass(std::string("some_setting"),classPtr),
  currentState(original)
{
  ...
}
  

edit: see my "answer" for what was causing this. After reading it, can anybody explain to me why it made a difference? I didn't change anything in the header, and obviously the object file was being rebuilt because of my print statements appearing when I put them in and the lack of seeing the bug under one build but not the other?

For a good explanation, I'll mark it as the answer to this question.

回答1:

For posterity:

It appears as though the make script isn't pickup up the changes to these files for some reason. Manually deleting the objects rather than letting our "clean" target in the makefile caused a full rebuild (which took some time), and the problem disappeared.