JohnOne Posted September 26, 2012 Share Posted September 26, 2012 (edited) Thanks for reading, this is related to C++ I'm having an issue with my code but I cannot seem to track the cause down. What is happening is that a private class member variable which I do not intentionally change in my code, is somehow getting changed. I have used C++ in visual studio before but only really procedural coding and have usually found bugs my manual eye examination of it, but now I find myself needing help. Here is an example of the structure of my code. expandcollapse popupclass TestClass { private: __int64 var1; // I need to monitor this value __int64 var2; __int64 var3; __int64 var4; __int64 var5; __int64 instance; public: void SetVar1(__int64 var){ var1 = var; } void SetVar2(__int64 var){ var2 = var; } void SetVar3(__int64 var){ var3 = var; } void SetVar4(__int64 var){ var4 = var; } void SetVar5(__int64 var){ var5 = var; } __int64 GetVar1(){ return var1; } __int64 GetVar2(){ return var2; } __int64 GetVar3(){ return var3; } __int64 GetVar4(){ return var4; } __int64 GetVar5(){ return var5; } void PrintAll(){ std::cout << "Instance: " << instance << "nn"; std::cout << "var1: " << var1 << "n"; // This var1 is displaying something other than it's initial value (-1) std::cout << "var2: " << var2 << "n"; std::cout << "var3: " << var3 << "n"; std::cout << "var4: " << var4 << "n"; std::cout << "var5: " << var5 << "n"; } TestClass (__int64 var) : var1(-1), var2(-1), var3(-1), var4(-1), var5(-1) { instance = var; } }; void TestFunc(TestClass &ftest){ /* ftest in func */ ftest.SetVar2(2222222222222); ftest.SetVar3(3333333333333); ftest.SetVar4(4444444444444); ftest.SetVar5(5555555555555); } int main () { /* TestClass test0(0); TestClass test1(1); TestClass test2(2); TestClass test3(3); TestClass test4(4); TestClass * atest[5]; atest[0] = &test0; atest[1] = &test1; atest[2] = &test2; atest[3] = &test3; atest[4] = &test4; */ TestClass mtest(1); // mtest in main TestFunc(mtest); mtest.PrintAll(); std::cin.get(); } Obviously there is a lot more going on in my code than shown here for example I also pass an array of class instance addresses to, and access from TestFunc as well as the instance seen here. My question is, how can I use VS2010 to step through my code while monitoring the value of the class member indicated. May be a noob question, I know but I'm not familiar with debugging like this if any one can show me the way I'd be delighted. Edited November 27, 2012 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
darthwhatever Posted September 26, 2012 Share Posted September 26, 2012 When I ran this snippet, this displays -1. As for stepping through the code, you can set breakpoints by Right Clicking > Breakpoint > Insert Breakpoint, or clicking on the gray area to the left of the line numbers. You can then view all your variables and their values while the code is running in the Locals window which should appear at the bottom of the VS window. If it does not, click Debug > Windows > Locals. Hope this helps! [font=arial, sans-serif]How is education supposed to make me feel smarter? Besides, every time I learn something new, it pushes some old stuff out of my brain. Remember when I took that home winemaking course, and I forgot how to drive?[/font][font=arial, sans-serif]<div>This is how you annoy a web developer.</span>[/font] Link to comment Share on other sites More sharing options...
JohnOne Posted September 26, 2012 Author Share Posted September 26, 2012 The snippet is just to show the basic structure of my code. Yes, that helped enormously. Thanks. All kinds of the wrong variable getting changed, while I'm watching it. Is there any problem with using __int64 on 32 bit OS in debug mode? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
darthwhatever Posted September 26, 2012 Share Posted September 26, 2012 (edited) #include <iostream> int main () { std::cout << "sizeof(int) = " << sizeof(int) << std::endl; std::cout << "sizeof(__int32) = " << sizeof(__int32) << std::endl; std::cout << "sizeof(__int64) = " << sizeof(__int64) << std::endl; std::cin.get(); }correctly shows _int64 being twice as large as a 32 bit intShouldn't be any problemLink to explanationEdit: Are you sure you want to use __int64? What kind of program could you possibly be writing that needs a range of –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (link)? Edited September 26, 2012 by darthwhatever [font=arial, sans-serif]How is education supposed to make me feel smarter? Besides, every time I learn something new, it pushes some old stuff out of my brain. Remember when I took that home winemaking course, and I forgot how to drive?[/font][font=arial, sans-serif]<div>This is how you annoy a web developer.</span>[/font] Link to comment Share on other sites More sharing options...
Richard Robertson Posted September 26, 2012 Share Posted September 26, 2012 One Google search away http://msdn.microsoft.com/en-us/library/aa295838%28VS.60%29.aspx#_core_setting_a_breakpoint_when_a_variable_changes_value Link to comment Share on other sites More sharing options...
JohnOne Posted September 26, 2012 Author Share Posted September 26, 2012 One Google search away http://msdn.microsoft.com/en-us/library/aa295838%28VS.60%29.aspx#_core_setting_a_breakpoint_when_a_variable_changes_valueThanks.For reference, the above link is for visual studio 6.0 and is not valid for VS 2010.There is no breakpoints option in the edit menu.Set a breakpoint, right click the breakpoint, select condition, add variable name. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted September 26, 2012 Author Share Posted September 26, 2012 #include <iostream> int main () { std::cout << "sizeof(int) = " << sizeof(int) << std::endl; std::cout << "sizeof(__int32) = " << sizeof(__int32) << std::endl; std::cout << "sizeof(__int64) = " << sizeof(__int64) << std::endl; std::cin.get(); } correctly shows _int64 being twice as large as a 32 bit int Shouldn't be any problem Link to explanation Edit: Are you sure you want to use __int64? What kind of program could you possibly be writing that needs a range of –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (link)? Thanks pal, It's just most likely my dodgy coding using an array of class references I am quite the novice you see. With viewing the locals like you showed me, I have determined that when I access an instance of a class that I have passed to function in an array, and change a member variable in it, values from a totally different class are being altered, and that is the problem. This will help me to discover why? I need __int64 (I think) because values I am working with are greater than the max int value and double value. Thank you very much for the help, I appreciate your time. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Richard Robertson Posted September 26, 2012 Share Posted September 26, 2012 Whoops. Sorry for the outdated link. Quick look at Visual Studio (I don't do much C++ debugging) indicates Debug>New Breakpoint>New Data Breakpoint is where you want. Link to comment Share on other sites More sharing options...
JohnOne Posted November 20, 2012 Author Share Posted November 20, 2012 I've come back to this project after a while and still I cant find bug.When I insert a breakpoint ot tracepoint on the line in question, and hover over it during debugI get the messageThe breakpoint will not currently be hit. No executable code is associated with this line.Possible causes include: preprocessor directives or compiler/linker optimizations.So I cannot find where, when or what is causing the value to change.I'm adding he tracepoint at__int64 var1; // I need to monitor this value // line, because that is where it is declared in my TestClassand the only other references to it are the getters and setters I have, which are never called in the code.If anyone has any other suggestion on debugging methods I'd sure appreciate hearing them.Cheers for reading. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
danielkza Posted November 20, 2012 Share Posted November 20, 2012 Did you disable optimizations in the compilation options for the Debug configuration? Link to comment Share on other sites More sharing options...
JohnOne Posted November 20, 2012 Author Share Posted November 20, 2012 (edited) No, I don't see any options for compilation.Can you give me a hint where it might be in vs2010?EDIT:c/c++ -> optimization -> optimization = Disabled (/Od)I'll try turning it on.EDIT2:None of the other settings are compatible it says, and the preprocessorslisted are WIN32_DEBUG_CONSOLEwith inherited_UNICODEUNICODEBut I don't even know what that means.EDIT3:The only thing which is coming into my mind is the use of_atoi64() which I'm passing unsigned char *It seems to work fine with everything, but it just could be the problem.When I was searching for way of unsigned char to int64I read that it does not matter whether unsigned or not, now I'm not so surebut cannot find any more info on that. Edited November 20, 2012 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Mat Posted November 20, 2012 Share Posted November 20, 2012 A declaration may not actually translate to something being executed... All those class fields are probably allocated in one statement. For a start, add a constructor to the class, add a dummy statement and break on that, it will show you the initial value. Then step out and it should take you to where you are initializing the class, and you can then set a breakpoint for when that location in memory is changed as discussed above. From there you can either run it or step through the program. AutoIt Project Listing Link to comment Share on other sites More sharing options...
JohnOne Posted November 20, 2012 Author Share Posted November 20, 2012 (edited) There is a constructor in the class, should add the dummy statement in the constructor? expandcollapse popupclass TestClass { private: __int64 var1; // I need to monitor this value __int64 var2; __int64 var3; __int64 var4; __int64 var5; __int64 instance; public: void SetVar1(__int64 var){ var1 = var; } void SetVar2(__int64 var){ var2 = var; } void SetVar3(__int64 var){ var3 = var; } void SetVar4(__int64 var){ var4 = var; } void SetVar5(__int64 var){ var5 = var; } __int64 GetVar1(){ return var1; } __int64 GetVar2(){ return var2; } __int64 GetVar3(){ return var3; } __int64 GetVar4(){ return var4; } __int64 GetVar5(){ return var5; } void PrintAll(){ std::cout << "Instance: " << instance << "nn"; std::cout << "var1: " << var1 << "n"; // This var1 is displaying something other than it's initial value (-1) std::cout << "var2: " << var2 << "n"; std::cout << "var3: " << var3 << "n"; std::cout << "var4: " << var4 << "n"; std::cout << "var5: " << var5 << "n"; } TestClass (__int64 var) : var1(-1), var2(-1), var3(-1), var4(-1), var5(-1) { instance = var; } }; void TestFunc(TestClass &amp;amp;amp;ftest){ /* ftest in func */ ftest.SetVar2(2222222222222); ftest.SetVar3(3333333333333); ftest.SetVar4(4444444444444); ftest.SetVar5(5555555555555); } int main () { /* TestClass test0(0); TestClass test1(1); TestClass test2(2); TestClass test3(3); TestClass test4(4); TestClass * atest[5]; atest[0] = &test0; atest[1] = &test1; atest[2] = &test2; atest[3] = &test3; atest[4] = &test4; */ TestClass mtest(1); // mtest in main TestFunc(mtest); mtest.PrintAll(); std::cin.get(); } EDIT: indenting Edited November 27, 2012 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted November 20, 2012 Author Share Posted November 20, 2012 I don't know why I never thought earlier, but I just littered main code with Modified mtest.PrintAll(); just to print the culprit var and found at least where it's happening. Thank you for your help folks. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted November 20, 2012 Author Share Posted November 20, 2012 (edited) My tail is curled between my legs here, I know where the problem lies and have created a runnable reproducer, in the hope someone has the time and inclination to look at or run it. I have realised that I must be doing something fundamentally wrong, but I just do not know what. Hoping. John. expandcollapse popup#include "stdafx.h" #include <iostream> class TestClass { private: __int64 var1; // I need to monitor this value __int64 var2; __int64 var3; __int64 var4; __int64 var5; __int64 instance; public: void SetVar1(__int64 var){ var1 = var; } void SetVar2(__int64 var){ var2 = var; } void SetVar3(__int64 var){ var3 = var; } void SetVar4(__int64 var){ var4 = var; } void SetVar5(__int64 var){ var5 = var; } __int64 GetVar1(){ return var1; } __int64 GetVar2(){ return var2; } __int64 GetVar3(){ return var3; } __int64 GetVar4(){ return var4; } __int64 GetVar5(){ return var5; } void PrintAll(){ std::cout << "Instance: " << instance << "nn"; std::cout << "var1: " << var1 << "n"; // This var1 is displaying something other than it's initial value (-1) std::cout << "var2: " << var2 << "n"; std::cout << "var3: " << var3 << "n"; std::cout << "var4: " << var4 << "n"; std::cout << "var5: " << var5 << "n"; } TestClass (__int64 var) : var1(-1), var2(-1), var3(-1), var4(-1), var5(-1) { instance = var; } }; class DifferentClass { private: bool inuse; bool relevant; __int64 value1; __int64 value2; __int64 lastvalue; __int64 instance; public: //default constructor DifferentClass (__int64 num) : inuse(false), relevant(false), value1(__int64(0)), value2(__int64(0)), lastvalue(__int64(0)) { instance = num; } //setters void Sinuse(bool var); void Srelevant(bool var); void Svalue1(__int64 var); void Svalue2(__int64 var); void Slastvalue(__int64 var); void Sinstance(__int64 var); //getters bool Ginuse(void); bool Grelevant(void); __int64 Gvalue1(void); __int64 Gvalue2(void); __int64 Glastvalue(void); __int64 Ginstance(void); //Destructor ~DifferentClass () { } }; //Setters void DifferentClass::Sinuse(bool var) { inuse = var; } void DifferentClass::Srelevant(bool var) { relevant = var; } void DifferentClass::Svalue1(__int64 var){ value1 = var; } void DifferentClass::Svalue2(__int64 var){ value2 = var; } void DifferentClass::Slastvalue(__int64 var){ lastvalue = var; } void DifferentClass::Sinstance(__int64 var){ instance = var; } //Getters bool DifferentClass::Ginuse() { return inuse; } bool DifferentClass::Grelevant() { return relevant; } __int64 DifferentClass::Gvalue1(){ return value1; } __int64 DifferentClass::Gvalue2(){ return value2; } __int64 DifferentClass::Glastvalue(){ return lastvalue; } __int64 DifferentClass::Ginstance(){ return instance; } // Where DifferentClass values are being changed void _func(DifferentClass * atest){ // I believe the problem lies in this piece of code // because this is always the executed before the culprit value changes for (int i = 0; i < 20; i++) { atest[i].Svalue1(i+100000); atest[i].Svalue2(i+200000); atest[i].Slastvalue(i+300000); } } int main () { TestClass mtest(1); // mtest in main DifferentClass test0(0); DifferentClass test1(1); DifferentClass test2(2); DifferentClass test3(3); DifferentClass test4(4); DifferentClass * atest[5]; atest[0] = &test0; atest[1] = &test1; atest[2] = &test2; atest[3] = &test3; atest[4] = &test4; for (int n = 0; n < 20; n++) { //func changes values in DifferentClass instance _func(*atest); //Print values in TestClass mtest.PrintAll(); } std::cin.get(); } Edited November 27, 2012 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted November 20, 2012 Author Share Posted November 20, 2012 Sorry, Here is a summary of what goes wrong. There are two classes, one instance of TestClass and 5 instances of DifferentClass values are changed in all instances of DifferentClass , but values in TestClass take on those changed in the instances of DifferentClass. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
wraithdu Posted November 20, 2012 Share Posted November 20, 2012 Any difference if you make your for loop variable i an __int64 instead of an int? Link to comment Share on other sites More sharing options...
JohnOne Posted November 20, 2012 Author Share Posted November 20, 2012 No, I have tried that AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
wraithdu Posted November 20, 2012 Share Posted November 20, 2012 To be honest, your code compiles but crashes in MinGW, probably with a memory error (I don't know shit about debugging). I'm playing with it though. I though I read somewhere that arrays of pointers was bad... maybe I'm mistaken. Link to comment Share on other sites More sharing options...
Solution wraithdu Posted November 20, 2012 Solution Share Posted November 20, 2012 (edited) Ok, so I never got the changing values in your different class, but the app was just crashing. Try this.expandcollapse popup#include <iostream> #include "windows.h" class TestClass { private: __int64 var1; // I need to monitor this value __int64 var2; __int64 var3; __int64 var4; __int64 var5; __int64 instance; public: void SetVar1(__int64 var){ var1 = var; } void SetVar2(__int64 var){ var2 = var; } void SetVar3(__int64 var){ var3 = var; } void SetVar4(__int64 var){ var4 = var; } void SetVar5(__int64 var){ var5 = var; } __int64 GetVar1(){ return var1; } __int64 GetVar2(){ return var2; } __int64 GetVar3(){ return var3; } __int64 GetVar4(){ return var4; } __int64 GetVar5(){ return var5; } void PrintAll(){ std::cout << "Instance: " << instance << "nn"; std::cout << "var1: " << var1 << "n"; // This var1 is displaying something other than it's initial value (-1) std::cout << "var2: " << var2 << "n"; std::cout << "var3: " << var3 << "n"; std::cout << "var4: " << var4 << "n"; std::cout << "var5: " << var5 << "n"; } TestClass (__int64 var) : var1(-1), var2(-1), var3(-1), var4(-1), var5(-1) { instance = var; } }; class DifferentClass { private: bool inuse; bool relevant; __int64 value1; __int64 value2; __int64 lastvalue; __int64 instance; public: //default constructor DifferentClass (__int64 num) : inuse(false), relevant(false), value1(0), value2(0), lastvalue(0) { instance = num; } //setters void Sinuse(bool var); void Srelevant(bool var); void Svalue1(__int64 var); void Svalue2(__int64 var); void Slastvalue(__int64 var); void Sinstance(__int64 var); //getters bool Ginuse(void); bool Grelevant(void); __int64 Gvalue1(void); __int64 Gvalue2(void); __int64 Glastvalue(void); __int64 Ginstance(void); //Destructor ~DifferentClass () { } }; //Setters void DifferentClass::Sinuse(bool var) { inuse = var; } void DifferentClass::Srelevant(bool var) { relevant = var; } void DifferentClass::Svalue1(__int64 var){ value1 = var; } void DifferentClass::Svalue2(__int64 var){ value2 = var; } void DifferentClass::Slastvalue(__int64 var){ lastvalue = var; } void DifferentClass::Sinstance(__int64 var){ instance = var; } //Getters bool DifferentClass::Ginuse() { return inuse; } bool DifferentClass::Grelevant() { return relevant; } __int64 DifferentClass::Gvalue1(){ return value1; } __int64 DifferentClass::Gvalue2(){ return value2; } __int64 DifferentClass::Glastvalue(){ return lastvalue; } __int64 DifferentClass::Ginstance(){ return instance; } // Where DifferentClass values are being changed void _func(DifferentClass * atest[]){ // I believe the problem lies in this piece of code // because this is always the executed before the culprit value changes for (int i = 0; i < 5; i++) { atest[i]->Svalue1(i+100000); atest[i]->Svalue2(i+200000); atest[i]->Slastvalue(i+300000); } } int main () { TestClass mtest(1); // mtest in main DifferentClass test0(0); DifferentClass test1(1); DifferentClass test2(2); DifferentClass test3(3); DifferentClass test4(4); DifferentClass * atest[5]; atest[0] = &test0; atest[1] = &test1; atest[2] = &test2; atest[3] = &test3; atest[4] = &test4; for (int n = 0; n < 20; n++) { //func changes values in DifferentClass instance _func(atest); //Print values in TestClass mtest.PrintAll(); } std::cin.get(); }atest is an array of pointers, so you pass the array (a pointer itself) to _func, and the parameter is an array of pointers to your class. This runs with no crash for me. Be careful in _func... there's nothing to stop you from going out of bound on the array and crashing from a memory access error (which was my first crash, as your code increments i to 19, when you only have a 5 element array). It might be better to use something with a known capacity here, a vector or something (I'm sure others could suggest better container classes to you, my knowledge is admittedly limited). Edited November 20, 2012 by wraithdu JohnOne 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now