Code breaking when trying to set member variable in constructor - c++

I have a class like this:
class Player
{
public:
Player(Board * someBoard);
void setSide(char newSide);
protected:
Board * board;
char side;
};
and its implementation is as such:
Player::Player(Board * someBoard)
{
board = someBoard;
side = '0';
}
void Player::setSide(char newSide)
{
side = newSide;
}
Now I have another class inheriting from it:
class HumanPlayer : public Player
{
public:
HumanPlayer(Board * someBoard);
};
And its short implementation is this:
HumanPlayer::HumanPlayer(Board * someBoard) : Player(someBoard)
{
}
Now the problem is the side = '0'; line makes the program freeze (the window turns white in Windows 7, not sure if that means it froze or crashed). Commenting it out make the program run fine (and it's okay to comment it out because the variable isn't used anywhere yet).
What is causing the error and how can I fix it?
EDIT!
After printing out some stuff to an fstream, all of a sudden the program worked. I tried commenting the printing out. It still worked. I tried deleting the debugging code I added in. It still worked. So now my code is exactly the same as listed above, but it magically works now.
So what do I do now? Ignore the anomaly? Could it have been a compiler mistake?

I suspect the problem isn't what you think it is.
It sounds like a memory corruption issue of some sort, but it's really impossible to tell based on the information provided. I have two suggestions for you:
Either post the smallest complete program that demonstrates the problem, or
Try a valgrind-type tool to see if it helps you figure out what's going on.
Or, better yet, start by looking at the state of the program in the debugger (once it's hung.)

Is it possible that you are using two incompatible definitions of your Player class, defined in different header files? If the definitions have different sizes, then the 'size' member might lie outside the memory block allocated for the class instance.
Edit I see that your problem has disappeared. So it was probably a module that didn't get re-compiled after a change in the class definition; but now that you've re-compiled everything, the problem has fixed itself.

Related

Adding a new private member variable to a class causes a memory gap for all following variable (C++17)

I encountered a weird problem, when I modify a header file (specifically add a private member variable) I then have a weird, memory related I believe, bug.
Here is some exemple to code to illustrate:
Original header file:
#includes
class myClass : public otherClass1 {
Q_OBJECT
public:
myClass(params);
private:
std::reference_wrapper<otherClass2> _Var1;
std::vector<QRadioButton*> _Var2;
QComboBox * _Var3;
size_t _Var4;
};
Original source file:
#includes
myClass::myClass(params){
//Do stuff
_Var4 = 5;
//Rest of the stuff to be done
}
Now if add _testVar under _Var4 everything's good, but adding _testVar between _Var4 and _Var3 makes _Var4 bug, if I add _testVar under _Var2 then _Var3 and _Var4 bug.
I also noticed that if _Var3 and _Var4 bug then modifying _Var3 actually modifies _Var4.
From my (limited) understanding this is caused by a memory gap (meaning that _testVar is now _Var3 and _Var3 is _Var4 (memory wise)).
Now I'm not expecting to recieve a flat out answer for my problem here but some pointers and hints would help greatly, because I'm completely clueless right now as to why this is happening.
PS: I'm using Qt 5.15.1, not that it's related I believe but maybe it's worth mentioning.
EDIT: #markus-nm was right, it was a MOC-related issue. Clearing all of the generated outputs (forcing MOC to be re-run) solved the issue. This solution wasn't obvious to me due to the specific environment and tools I have to use at my work.

Can you have too many variables in a header?

I kept getting runtime errors at one spot of my code and narrowed it down to a bool that was initialized to 205. I looked this issue up and that's apparently garbage that an uninitialized bool can have.
Okay, but I initialized it. This boolean value is in the private section of the header file. The class contains a method to set the value and another to return the value. Pretty bog standard stuff. So I set up a quick little test.
thing.setValue(false);
cout << thing.getValue() <<endl;
(not the actual names, but just to keep it simple)
It still spit out 205. Literally one statement setting the variable, then the very next simply asking to repeat it back and it's giving me garbage.
Somewhat perplexed, I took a look at the header file. There's an int declared right above the bool in the header, so I did a similar test with that one. It works just fine. I swap the order of the two in the header. Now the bool works and the int doesn't. So there's one vector<int> in the header above the two that it turns out I'm no longer using because I've replaced the method that used it. So I delete that, lo and behold it now works.
I can't seem to find any information on this. I imagine it's likely I just don't know what to search for to find the answer. I'm hoping it's a really obvious and dumb mistake someone more experienced can slap me over the head with so I can move on.
For code example, it's just a simple header file like any other that looks like
#ifndef concept_H
#define concept_H
class concept {
private:
//...
//...
//...
int x;
bool y;
public:
//bunch of methods//
void setY(bool whatever);
bool isY();
};
#endif
with the method implementation being equally trivial
void concept::setY(bool whatever){
y=whatever;
}
bool concept::isY(){
return y;
}
This isn't the actual code; there's a lot of other stuff there on the periphery and I just don't know what to include as relevant. Hoping again that it's a dumb mistake I'm making and someone can just tell me right away, but if not I can provide more. I just need help to even know where to begin to look.
No, there is no set limit on the number of variables you can declare. That is not the cause of your issue.

Weird Intel C++ compiler error

I'm working on this VST convolution plugin (Windows 7 64bit, VS2010) and I decided to try the Intel c++ compiler. I was in the process of optimizing the algorithm so I had a backup project in case of any screw ups and one I was doing experiments on. Both projects would compile and run with no problems. After installing the Intel compiler though the project I was experimenting on would cause a heap corruption error, so I start debugging to track down the problem but I can't find the line of code that causes it since the heap corruption error is not triggered during execution but after the termination of the DLL (there are also no access violations showed by the debugger).
At this point I start cutting out parts of the code to see if I can isolate the problem and I discover (obviously) that it was the class I was eperimenting on. Now here comes the weird part: I can change the code inside the methods but as soon as I add a variable to the backup class (the one that works fine), even an int, I get the heap corruption error, just a decleared and never referenced variable is enough.
This is the class CRTConvolver:
class CRTConvolver
{
public:
CRTConvolver();
~CRTConvolver();
bool Init(float* Imp, unsigned ImpLen, unsigned DataLen);
void doConv(float* input);
Buff Output;
int debug_test;
private:
void ZeroVars();
int Order(int sampleFrames);
template <class T> void swap ( T& a, T& b );
Buff *Ir_FFT,*Input_FFT,Output2,Tmp,Prev,Last;
float *Tail;
unsigned nBlocks,BlockLen,Bl_Indx;
IppsFFTSpec_R_32f* spec;
};
that "int debug_test;" makes the difference between a perfectly working VST module and a program that crashes on initialization from Cubase.
always for debugging purposes here are destr and constr:
CRTConvolver::CRTConvolver()
{
//IppStatus status=ippInit();
//ZeroVars();
}
CRTConvolver::~CRTConvolver()
{
//Init(NULL,NULL,NULL);
}
Here is what class Buff looks like:
class Buff {
public:
Buff();
Buff(unsigned len);
~Buff();
float* buff;
unsigned long length;
private:
void Init(unsigned long len);
void flush();
friend class CRTConvolver;
}
Buff::Buff()
{
length=NULL;
buff=NULL;
}
Buff::~Buff()
{
// flush();
}
basically this class if created and destructed does absolutely nothing, it just contains the length and buff variables. If I also bypass those two variable initializations the heap error goes away.
The software crashes on simple construction and subsequent destruction of the class CRTConvolver even though all it does is nothing, this is the part that really doesn't make sense to me...
As a side note, I create my CRTConvolver class like this:
ConvEng = new CRTConvolver[NCHANNELS];
If I declare it like this instead:
CRTConvolver ConvEng[NCHANNELS];
I get a stack corruption error around variable ConvEng.
If I switch back to Microsoft compiler the situation stays the same even when compiling and running the exact same version that could run without errors before....
I can't stress enough the fact that before installing the Intel compiler everything was running just fine, is it possible that something went wrong or there's an incompatibility somewhere ?
I'm really running out of ideas here, I hope someone will be able to help.
thanks
Going to guess, since the problem is most likely undefined behavior, but in some other place in your code:
Obey the rule of three. You should have a copy constructor and assignment operator. If you're using std containers, or making copies or assignments, without these you run into trouble if you delete memory inside the destructor.
It looks to me that the CRTConvolver default constructor (used in creating an array) is writing to memory it doesn't own. If the Intel compiler has different class layout rules (or data alignment rules), it might be unmasking a bug that was benign under the Microsoft compiler's rules.
Does the CRTConvolver class contain any instances of the Buff class?
Updated to respond to code update:
The CRTConvolver class contains four instances of Buff, so I suspect that is where the problem lies. It could be a version mismatch -- the CRTConvolver class thinks that Buff is smaller than it really is. I suggest you recompile everything and get back to us.

Error Writing to Memory of Particular Data Member

Okay, I have a struct, TextBlock, that simulates moving blocks of text around the screen. Here's the header:
struct TextBlock
{
RECT textArea;
RECT rectArea;
double whatBlock;
double x;
double y;
double angle;
double speed;
double width;
double height;
char *word;
bool stuck;
};
When it's like this, everything works perfectly fine. The problem comes when I add another member that I need. The way it works is that I have two arrays of TextBlocks. The first is for moving ones, the second is for ones that don't move, signifying where the moving ones need to go. The words are all randomized from a sentence to a jumble, so this data member will be set (commented out) to the index of which static block belongs to the moving one so I know when it's in the right place.
int whatBlock;
After creating this, I go through all of the created objects and set
tb[i][j].whatBlock = 0; //same area as other data members being set, moving text
stb[i][j].whatBlock = 0; //static text block
When I try to run this, without doing anything else to the data member, it comes up with an error:
The instruction at [address] referenced memory at [different address]. The memory could not be "written".
Note that if I don't try to modify it, and just create the data member, it works.
At this point of almost being done and having tons of these kinds of problems, I'm getting a bit fed up with this program >.> Any help at all on this would be greatly appreciated.
EDIT: This issue is now fixed. I replied to the accepted answer with the explanation, but it poses another problem, even if it doesn't affect this program.
Force a rebuild of everything. You may have an object file that is out-of-date with respect to the header file that defines TextBlock
If that doesn't fix it, run your program under a debugger and see what the faulting instruction is. Either that will allow you to fix the program, or you can ask again with mroe informatin.
Without you posting more code, I can only tell that you likely have a memory corruption bug in your program - i.e. you are reading or writing beyond the end of allocated memory.
If you post more code, I'll edit this answer accordingly.
I can't really give advices since we cannot access the complete source code.
Anyway, I can suggest you that it may be not in the struct TextBlock where really hides the bug. For instance, every access to TextBlock's member means that you are accessing to this hidden variable.
If this pointer is corrupted, you may experience problem where you don't expect it, leading you to search in the wrong places.

VS2008 internal compiler error

I'm consistently running into an internal compiler error while attempting to switch from MSVC6 to MSVC 2008. After much work commenting out different parts of the program, I've traced the error to two lines of code in two different CPP files. Both of these CPP files compile successfully, yet somehow have an effect on whether or not the error manifests in other files.
Both of those lines involve instantianting several complex, nested templates. They also appear to be the only places in the app that use an abstract class as one of the template parameters. That said, I'm far from certain that the issue involves either abstract classes or templates, it's just the most obvious thing I've noticed. I can't even be sure that these lines are significant at all. Here's what they look like, though:
m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash);
So we've got SObjDict, a templatized dictionary class, SIDataSource, an abstract interface, and the parameter is a pointer to a static member function of RWCString.
I've been playing around with the code some, and I can occasionally get the error to move from one CPP file to another (for instance, I changed a bunch of template declarations from using class to typename), but I can't find any rhyme or reason to it.
I'm at a loss as to how to debug this issue further. The exact error output by the compiler (with the name of my source file changed) is below. There is no mention of it anywhere on the internet. I'm pretty desperate for any advice on how to proceed. I don't expect someone to say "oh, you just need to do XYZ", but a pointer on how to debug this sort of issue would be greatly appreciated.
1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905)
The trick seems to be disabling precompiled headers. I have no idea why that solves the problem, and it's very unfortunate since my build time for the affected project has gone from less than 30 secs to nearly 5 minutes, but at least I can progress forward.
It's a reasonable bet to assume that p2symtab.c is (part of) the symbol table code. This would immediately explain how the upgrade caused it; this code has been rewritten. (Remember the 255 character length warnings of VC6?)
In this case, there is no new entry in the symbol table, so it's likely a lookup in the symbol table failing spectactularly. It would be interesting to see if the context in which th name lookup happens affects the result. For instance, what happens if you change the code to
typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource;
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash);
This will force another symbol table entry to be created, for SObjDict_RWCString_SIDataSource. This entry is sort of a symbolic link to the template instantiation. The new name can (and must) be looked up on its own.
Start breaking it down into smaller parts. My first guess is the pointer to the static function is going to be the problem. Can you make a dummy non-template class with the same parameter in the constructor? Does it compile if you don't use an abstract class in the template?
Looks like I'm sending you in the wrong direction, the following compiles fine in 2008:
class thing {
public:
static void hash( short sht ) {
}
void hash( long lng ) {
}
};
class thing2 {
public:
thing2( void (short ) ){}
};
int _tmain(int argc, _TCHAR* argv[])
{
thing2* t = new thing2( &thing::hash );
delete t;
return 0;
}
The principle remains though, remove/replace complex elements until you have code that compiles and you'll know what is causing the problem.
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c
i also observed the same error when i try to build my vs 2005 code to vs 2008. but it happen till i have not installed Service pack of VS 2008...
have you installed Service pack... i think this will resolved your issue....
This typically happens with template instantiation. Unfortunately it could be caused by many things, but 99% of the time your code is subtly invoking undefined behavior.