Jump to content
  • Advertisement
Sign in to follow this  
VanillaSnake21

C++ Pointer becomes invalid for unknown reason

This topic is 401 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've restructured some of my code to use namespaces and started getting problems in a module that was working correctly previously. The one in question is a DebugWindow, what happens is I give it a pointer to a variable that I want to monitor/change and it's job is to display that variable in a separate window along with a some + and - buttons to in/decrement the variable.

These are the relevant portions:

 

WindowManager.h

namespace WindowManager
	{

		/* WindowManager functions snipped */


		namespace DebugWindow
		{
			void AddView(double* vard, std::wstring desc, double increment);
			void AddView(std::wstring* vars, std::wstring desc);
			void CreateDebugWindow(int width, int height, int x, int y);

		}

	}

 

 

Application.cpp is the main app, it calls the above functions to set the watch on the variables I need to see in real-time

void ApplicationInitialization()
{

	//create the main window
	UINT windowID = SR::WindowManager::CreateNewWindow(LocalWindowsSettings);

	//initialize the rasterizer
	InitializeSoftwareRasterizer(SR::WindowManager::GetWindow(windowID));

	//create the debug window
	SR::WindowManager::DebugWindow::CreateDebugWindow(400, LocalWindowsSettings.clientHeight, LocalWindowsSettings.clientPosition.x + LocalWindowsSettings.clientWidth, LocalWindowsSettings.clientPosition.y);


	//display some debug info
	SR::WindowManager::DebugWindow::AddView((double*)&gMouseX,TEXT("Mouse X"), 1);
	SR::WindowManager::DebugWindow::AddView((double*)&gMouseY, TEXT("Mouse Y"), 1);

}

 

The variables gMouseX and Y are globals in my application, they are updated inside the App's WindProc inside the WM_MOUSEMOVE like so :


	case WM_MOUSEMOVE:
	{
		gMouseX = GET_X_LPARAM(lParam);
		gMouseY = GET_Y_LPARAM(lParam);
		
		/* .... */

	}break;

 

 

Now inside the AddView() function that I'm calling to set the watch on the variable

	void AddView(double* vard, std::wstring desc, double increment)
			{
				_var v;
				v.vard = vard; // used when variable is a number
				v.vars = nullptr; // used when varialbe is a string (in this case it's not)
				v.desc = desc;
				v.increment = increment;

			
				mAddVariable(v);

			}

 

_var is just a structure I use to pass the variable definition and annotation inside the module, it's defined as such

	struct _var
			{
				double* vard;       //use when variable is a number
				double increment;   //value to increment/decrement in live-view
				std::wstring* vars; //use when variable is a string
				std::wstring desc;  //description to be displayed next to the variable

				int minusControlID; 
				int plusControlID;

				HWND viewControlEdit; //WinAPI windows associated with the display, TextEdit, and two buttons (P) for plus and (M) for minus.
				HWND viewControlBtnM;
				HWND viewControlBtnP;

			};

 

So after I call AddView it formats this structure and passes it on to mAddVariable(_var), here it is:

void mAddVariable(_var variable)
			{

				//destroy and recreate a timer
				KillTimer(mDebugOutWindow, 1);
				SetTimer(mDebugOutWindow, 1, 10, (TIMERPROC)NULL);
				
				//convert the variable into readable string if it's a number
				std::wstring varString;
				if (variable.vard)
					varString = std::to_wstring(*variable.vard);
				else
					varString = *variable.vars;


				//create all the controls
				variable.viewControlEdit = CreateWindow(/*...*/); //text field control
  
				variable.minusControlID = (mVariables.size() - 1) * 2 + 1;
				variable.viewControlBtnM = CreateWindow(/*...*/); //minus button control
					
			
				variable.plusControlID = (mVariables.size() - 1) * 2 + 2;
				variable.viewControlBtnP = CreateWindow(/*...*/); //plus button control
				


				mVariables.push_back(variable);
			}

 

I then update the variable using a timer inside the DebugWindow msgproc

case WM_TIMER:
				{
					switch (wParam)
					{

					case 1: // 1 is the id of the timer
					{
						for (_var v : mVariables)
						{
							SetWindowText(v.viewControlEdit, std::to_wstring(*v.vard).c_str());
						}

					}break;

					default: break;

					}
				
				}; break;

 

When I examine the mVariables, their vard* is something like 1.48237482E-33#DEN. Why does this happen?

 

Also to note is that I'm programming in C like fashion, without using any objects at all. The module consists of .h and .cpp file, whatever I expose in .h is public, if a function is only exposed in .cpp it's private . So even though I precede some functions with m_Function it's not in a member of a class but just means that it's not exposed in the header file, so it's only visible within this module.

 

Thanks.

 

 

Edited by VanillaSnake21

Share this post


Link to post
Share on other sites
Advertisement

Code like 

(double*)&gMouseX

isn't converting the value of gMouseX from an integer (which I'm assuming it is) to a double. It's converting the address of an integer to an address of a double. The code you give that address to assumes the address points to a double, and treats it as such. However, the bit patterns of the number "43" as a double are very different from the bitpatterns of the number "43" as an integer. Thus you are likely to get bogus results when you try to interpret them the way you're doing.

43, as an integer, has a 64-bit bitpattern of 00101011 (higher bits are all zero).

43.0, a double, has a 64-bit bitpattern of 01000000 01000101 10000000 00000000 00000000 00000000 00000000 00000000. 

The bitpattern 00101011 as a double is 2.12448227711736013995924580933E-322.

(these values based on some random double bit calculator I found on the internet; accuracy not guaranteed, but the point is that they are very different representations)

In order for this technique of yours to work you're going to need to add support for each actual type of variable you're going to support (not just conceptual types like "number" and "string").

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!