Problem overview: A member variable is correctly set in the setter but read from a wrong address in the getter.
Project set up: I am using a microcontroller of the STM32F4 series. The project contains C- and C++-code. The latter is used for a GUI which is made with TouchGFX. I use the compiler of Keil 5.29.0.0.
Problem details: There is a class with a lot of data (the Model class in TouchGFX). In this class, the following happened several times: I added a new private member variable to the class and initialized it in the initializer list of the constructor. I created the simplest version of getter and setter, i.e. setting the value given by the parameter resp. returning the member variable, without any checks or error handling. Then I ran the system and did not get the expected value on the GUI. Stepping through with the debugger showed that the setter and the getter were linked to different memory adresses: The setter wrote to an address in the RAM (as expected), but the getter read from an address in the flash which had nothing to do with the class.
Code example:
Model.hpp:
class Model
{
public:
Model();
void bind(ModelListener* listener)
{
modelListener = listener;
}
void tick();
/* Several getters and setters... */
uint8_t getTheProblematicVariable();
void setTheProblematicVariable(uint8_t theVariable);
protected:
ModelListener* modelListener;
private:
/* Several variables */
uint8_t theProblematicVariable;
};
Model.cpp:
Model::Model()
: modelListener(0),
/* Several variables */
theProblematicVariable(90)
{}
/* ... Implementation of the getters and setters of all other variables */
uint8_t getTheProblematicVariable()
{
return theProblematicVariable;
}
void setTheProblematicVariable(uint8_t theVariable)
{
theProblematicVariable = theVariable;
}
Trial and error:
- Moving the variable around, i.e. changing its position in the list of the member variables (and in the initializer list) changed the address from which the getter read but it was still an address in the flash.
- Clean and rebuild did not fix it.
- Declaring the member variable as static solves the problem, but that is more lika a workaround than a solution because I don't understand what is going wrong.
Internet search:
- It is not about dynamically allocated elements as here: Pointer pointing to wrong address?
- The problem is not the same as here: C++ "Getter" method throwing access violation when trying to return private variable in same class
- A comment to this problem (C++ calling completely wrong (virtual) method of an object) talks about the vtable and linking which sounds interesting but the solution was about casting and subclasses which is not applicable to my problem.
- As there are no virtual functions called in the constructor, it is not the same problem as here: Getter returns wrong value. But the author's suggestion: "Second possible explanation is that due to some problem with project's Makefile, one of the source files was compiled against different libraries and there was some conflict when linking them together, maybe a memory collision." might apply to my problem. But I do not know how to check that.
Question: Where should I look deeper to find the problem?