strange problem with Window's open dialog

Started by
1 comment, last by Endurion 19 years, 10 months ago
Hello again to everyone. The next problem seems to me really weird. In my project I have a class that creates a trace file, for later viewing a replay of the mouse. Today I added a small member method in the main game class to open a level file using the windows normal open dialog. The problem is when this method is call the trace file won''t open. I''ve tried commenting out the call to this method, (giving the filename a default name) and it works just well. Can anybody tell me what could be wrong? I''m suspecting a memory leak or something. Here is the method that calls the windows dialog:

void CGame::OpenFile()
{
	OPENFILENAME file;
	char szFile[MAX_PATH];
	//const short int maxPath = 260;

	char currDirectory[MAX_PATH];
	
	GetCurrentDirectory(MAX_PATH, currDirectory);
	strcat(currDirectory, "\\Levels");

	ZeroMemory(&file, sizeof(file));
	file.lStructSize = sizeof(file);
	file.hwndOwner = NULL;
	file.lpstrFile = szFile;

	file.lpstrFile[0] = ''\0'';
	file.nMaxFile = sizeof(szFile);
	file.lpstrFilter = "Coucou Cache Level\0*.lvl\0All\0*.*\0";
	file.nFilterIndex = 1;
	file.lpstrFileTitle = NULL;
	file.nMaxFileTitle = 0;
	file.lpstrInitialDir = currDirectory;
	file.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

	GetOpenFileName(&file);
	m_cCurrentLevelFilename = szFile;
}
What''s weird is that the filename I get from this function (and deposit in m_cCurrentLevelFilename, is ok, as the level loads normally. The only trouble is that the trace file won''t get saved. Here are some examples how I create the trace object:

m_cTrace = new CTrace(m_cChildName, m_ucSelectTrace);
SaveLevel(m_cTrace->GetFileStream());
SaveTextLevel(m_cTrace->GetDebugFileStream());
m_cTimer = new CTimer();
m_cTimer->Start();
m_bUseTrace = true;
m_bGamePlaying = true;
and here is my constructor from CTrace:

CTrace::CTrace(string sChildsName_, unsigned char ucWriteCode_)
{
	SYSTEMTIME st;
	string filename;
	stringstream ssTmp;

	m_ucWriteCode = ucWriteCode_;

	if (m_ucWriteCode & WC_FILE) {
		GetLocalTime(&st);
		ssTmp << "Traces\\" << sChildsName_ << "\\" << st.wDay << "-" << st.wMonth << "-" << st.wYear 
			<< "-" << st.wHour << "-" << st.wMinute << ".trc";
		filename = ssTmp.str();
		
		m_cTraceFile.open(filename.c_str(), ios_base::binary | ios_base::out);
		if (!m_cTraceFile.is_open()) {
			// DVMTODO: Find a way to show messages to the guide.

			int lakis = 1;	// ton ipiame;!!!!!

		}
	}
	if (m_ucWriteCode & WC_NET) {
		//MessageBox(NULL, "test", "test", NULL);

	}

	if (m_ucWriteCode & WC_DEBUG) {
		GetLocalTime(&st);
		stringstream ssTmp1;
		ssTmp1 << "Traces\\" << sChildsName_ << "\\" << st.wDay << "-" << st.wMonth << "-" << st.wYear 
			<< "-" << st.wHour << "-" << st.wMinute << "D.trc";
		filename = ssTmp1.str();
		
		m_cDebugFile.open(filename.c_str(), ios_base::out);
		if (!m_cDebugFile.is_open()) {
			// DVMTODO: Find a way to show messages to the guide.

		}
	}
}
This is how I call the 2 methods in my program:

if (wParam_ == ''O'') {
		if (GetKeyState(VK_CONTROL) < 0) {
			// load the level

			OpenFile();
			LoadLevel(m_cCurrentLevelFilename.c_str());
		}
		else {
			m_bOutlineBalls = !m_bOutlineBalls;
			if (m_vBalls.size() > 0) {
				m_vBalls[0].SetOutline(m_bOutlineBalls);
			}
		}
	}
Again I point out that if I comment out the OpenFile(); line just above and leave m_cCurrentLevelFilename with the string it has from the CGame''s constructor the trace is saved just fine. Thank you for your time.
Advertisement
If I have understood things right, I'd say the problem is this line:

m_cCurrentLevelFilename = szFile;


It looks like this should copy the string to m_cCurrentLevelFilename, but what it does is to copy the memory adress of the data in szFile, so that both m_cCurrentLevelFilename and szFile points to the same place.
Since szFile is a local variable, when the function exits, that memory is freed and can no longer be used, so outside of the function, m_cCurrentLevelFilename is an invalid pointer.

What you need to do is to use the strcpy function, which performs what you intended.

Btw, I strongly suggest that you look into using the string class, instead of char[] for containing text. It makes life a whole lot easier.
/John
if m_cCurrentLevelFilename is a char array FunkyTune is right.

I also sense a disturbance in the current work directory. The open file dialog may set a new current work directory and your trace class uses a relative path it might end up trying to save the traces somewhere else (and fail because there's no "Traces" subdir).

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

This topic is closed to new replies.

Advertisement