I have a win32 c++ application & I getting all the environment variables & storing them in a map.
When I call the Win32 function FreeEnvironmentStrings() in my application I get a weird Windows Breakpoint in MSVC++. First I dont know what this means & why its occuring?
How can I fix my problem & what is going wrong?
This the function that I call in my main function & the one that causes the breakpoint:
std::map <tstring, tstring> GetEnvironmentVariablesEx()
{
// Post: Get all windows environment variables & store in a
// map(key=env.. variable name, value=env variable value)
std::map <tstring, tstring> envVariables;
TCHAR* environVar = GetEnvironmentStrings();
TCHAR* pos = _tcschr( environVar, _T('\0') );
// Skip over the "=::=::\0" of the environVar string
if ( pos != NULL ) { environVar = ++pos; pos = _tcschr( environVar, _T('\0') ); }
else return envVariables;
// I removed the following code because its long & distracting: the error still occurs without the code
// Code: ...use cstring functions to extract environ variables & values & store in map
FreeEnvironmentStrings( environVar ); // Breakpoint triggered here: "Windows has triggered a breakpoint in the application. This may be due to a corruption of the heap, which indicates a bug in myApp.exe or any of the DLLs it has loaded."
return envVariables;
}
You're changing what environVar points to, so you're not handing the FreeEnvironmentString function a valid environment string pointer.
Save the original environVar somewhere before modifying it and use that in the Free call.
TCHAR* tobefreeed = GetEnvironmentStrings();
TCHAR* environVar = tobefreeed;
...
FreeEnvironmentStrings( tobefreeed );
After you skip reserved characters environVar no longer points at data area allocated by GetEnvironmentStrings. This causes FreeEnvironmentStrings to fail.
Preserve original pointer intact (modify a copy if you need) and you'll solve the problem.
Related
Here is what is going on. When I try and run an AfxMessageBox from my CDialog extension class, I get an errror (see below). I've googled the internet but come up short. This is the only place the messagebox fails, and I know the rest of the code works (I stepped through it).
Does anyone know how to fix this?
Thanks in advance!
Error message when AFXMESSAGEBOX opens:
Unhandled exception at 0x014b4b70 in IsoPro.exe: 0xC0000005: Access violation reading location 0x34333345.
Code to launch AfxMessageBox, from within CDialog
LPTSTR temp;
mainPassword.GetWindowText((LPTSTR)temp,100);
CString cstr;
cstr.Format("mainPassword = %s",temp);
AfxMessageBox(cstr);
Code to display CDialog:
CEnterpriseManagementDialog* emd = new CEnterpriseManagementDialog();
emd->Create(IDD_ENTERPRISE_MANAGEMENT_DIALOG);
emd->ShowWindow(SW_SHOW);
The problem is how you use GetWindowText:
LPTSTR temp;
mainPassword.GetWindowText((LPTSTR)temp,100);
You are letting GetWindowText attempt to write to some unallocated memory passing the uninitialized temp pointer. If you really want to use a raw output buffer, you should allocate room for it before passing a pointer to GetWindowText, e.g.:
TCHAR temp[100];
mainPassword.GetWindowText(temp, _countof(temp));
// NOTE: No need to LPTSTR-cast
But, since you are using C++, you may want to just use a string class like CString, instead of raw buffers, e.g.:
CString password;
mainPassword.GetWindowText(password);
CString msg;
msg.Format(_T("mainPassword = %s"), password.GetString());
// or you can just concatenate CStrings using operator+ ...
AfxMessageBox(msg);
It looks like the variable temp is an uninitialized pointer (the definition of LPTSTR is a char *).
Try defining temp as an array instead:
TCHAR temp[64];
I encountered a problem when debugging my model (written in C++) in Eclipse CDT. The problem is that when I pass a structure variable, who contains various member variables such as string or vector, to a function by reference, the value of certain member variables are not updated in the scope of that function. More details are provided as below:
struct ModelConfig {
//... here are some other variables and constructors
vector<int> crop_list;
string path_to_input;
//....
};
Say now I start debugging in GDB, and here is the first function call :
void modelMain::setupModel( const ModelConfig & sim_setting ){
//... some operations to configure the model using 'sim_setting'
/* 1.3 - Initialize the land */
Set_Environment(k_farm_land, sim_setting);
// breakpoint here, printing out the value of 'sim_etting' shows 'sim_setting.path_to_input = "data/"' ; Then I enter into 'Set_Environment' function ...
//...
}
void Set_Environment(vector<Soil> & farm_land, const ModelConfig & sim_setting) {
int EXP_ID = sim_setting.EXP_ID;
string strTmp_a;
strTmp_a = sim_setting.path_to_input + "soil/parameters.txt"; // Problem is here: the GDB shows here that sim_setting.path_to_input = " ". I am expecting strTmp_a = "data/soil/parameters.txt" which now is "soil/parameters.txt" ;
//... operations for reading data
}
The sim_setting.path_to_input variable should hold the string value named data/, which is correct during the call in setupModel(...), but the value is lost (or the address is changed actually) during the call in Set_Environment(...)...
When using the GDB debug in Eclipse to trace the address of the variables, I notice that the address of sim_setting seems correct in both setupModel and Set_Environment, but the member variable of path_to_input and crop_list changed into other place, which cause the lost of data. The value of crop_list is created using .push_back().
I did not get the point since I am passing the variable by reference. The only thing that I can imagine is due to the value assignment of string and vector. Anyone have theory for this ? Thank you very much in advance !
I have a Win32 C++ application and I need to modify the command line arguments in the application. Specifically, I want to edit the command line arguments in such a way that GetCommandLineW() returns my new arguments.
Believe it or not, this works (since we have a non-const pointer to the character array):
LPTSTR args = GetCommandLineW();
LPTSTR new_args = L"foo --bar=baz";
wmemcpy(args, new_args, lstrlenW(new_args));
// ...
LPTSTR args2 = GetGommentLineW(); // <- equals "foo --bar=baz"
But I don't know how long much memory Windows allocates for the LPTSTR provided by GetCommandLineW().
Is there another way to do this? Or does anyone know if there is a predictable amount of memory allocated for the command line arguments?
GetCommandLineW() does not allocate any memory. It simply returns a pointer to a buffer that is allocated by the OS in the process's PEB structure when the process is created. That buffer exists for the lifetime of the process.
The cleanest and safest way to modify what that function returns is to modify the function. Install a detour so that any calls to the function from inside your process are re-routed to a function that you provide.
Use the following code to inspect on PEB structure, where the CommandLine (unicode) string lies.
On my machine, under both x86 and x64 CommandLine is right after ImagePathName, so I think there won't be more space for the former one either. Writing a longer string to that buffer does might cause an overflow.
#include <winnt.h>
#include <winternl.h>
int main()
{
// Thread Environment Block (TEB)
#if defined(_M_X64) // x64
PTEB tebPtr = (PTEB)__readgsqword((DWORD) & (*(NT_TIB*)NULL).Self);
#else // x86
PTEB tebPtr = (PTEB)__readfsdword((DWORD) & (*(NT_TIB*)NULL).Self);
#endif
// Process Environment Block (PEB)
PPEB pebPtr = tebPtr->ProcessEnvironmentBlock;
PRTL_USER_PROCESS_PARAMETERS ppPtr = pebPtr->ProcessParameters;
printf("ImagePathName:\tlen=%d maxlen=%d ptr=%p\n", ppPtr->ImagePathName.Length, ppPtr->ImagePathName.MaximumLength, ppPtr->ImagePathName.Buffer);
printf("CommandLine:\tlen=%d maxlen=%d ptr=%p\n", ppPtr->CommandLine.Length, ppPtr->CommandLine.MaximumLength, ppPtr->CommandLine.Buffer);
printf("GetCommandLineA:\tptr=%p\n", GetCommandLineA());
printf("GetCommandLineW:\tptr=%p\n", GetCommandLineW());
printf("Addr Delta between CommandLine and ImagePathName: %d\n", (char*)ppPtr->CommandLine.Buffer - (char*)ppPtr->ImagePathName.Buffer);
}
I'm writing C++ dll on Visual studio 2013. My dll should read parameters from ini file. So, I've created a function for this purpose (ReadConnectionSettings()). My static variable serverIP gets value properly during the function working, however once the function complete running the variable (serverIP) loses its value. What seems to be the problem?
static LPTSTR serverIP = _TEXT("");
void ReadConnectionSettings()
{
TCHAR url[256];
GetPrivateProfileString(_T("Connection"), _T("Url"), _T(""), url, 256, NameOfIniFile);
serverIP = url;
}
You are pointing the pointer serverIP at stack memory url.
This goes out of scope when the function exits, so your pointer is left pointing to junk.
What you could do is make serverIP a buffer instead, and copy the URL into it. Then it would persist.
That is:
static TCHAR serverIP[256] = _TEXT("");
Then:
_tcsnccpy(serverIP, url, 255);
Or as #DavidOtano suggested, you could keep your existing serverIP pointer, and use:
serverIP = _tcsdup(url);
But if you do this, you're dynamically allocating memory, so will need to remember to call:
free(serverIP);
when you no longer need it, to avoid a memory leak.
You're setting the static pointer variable to point at a local variable that does not exist anymore after the function has returned.
A good way to return a string from a function in a Windows program, is to return a std::wstring.
Try that.
Regarding LPTSTR and _TEXT, you only need this if you intend to support MFC in DLLs in Windows 9x. Is that the case? If not, just ditch that Microsoft silliness.
The code fixed according to above advice (off the cuff, untouched by compiler's hands):
auto connection_settings()
-> std::wstring
{
std::wstring url( 256, L'#' );
auto const n = GetPrivateProfileString( L"Connection", L"Url", L"", &url[0], url.size(), NameOfIniFile );
url.resize( n );
return url;
}
One nice property of this code is that it no longer modifies a global variable.
I'm having problems creating a tmx map from string input.
bool LevelManager::initLevel(int currentLevel)
{
const char* map;
try {
map = LevelManager::getLevel(currentLevel);
} catch (int) {
throw 1;
}
if(map != NULL){
CCLog("%s", map);
tileMap = CCTMXTiledMap::create(map);
tileMap->setAnchorPoint(ccp(0,0));
tileMap->setPosition(ccp(15,20));
this->addChild(tileMap, 5);
backgoundLayer = tileMap->layerNamed("Background");
} else {
throw 1;
}
return true;
}
Thats my code.
It is very unstable. Most of the times it crashes and sometimes it doesn't.
I'm loading my map from the string map. Wich is a const *char.
My map is named Level1.tmx and when i load the map like this: tileMap = CCTMXTiledMap::create("Level1.tmx"); it always works and never crashes.
And i know for a fact that the value of map is Level1.tmx because i log it in the line before the load.
When it crashes the log outputs this: (lldb)
and on the line tileMap->setAnchorPoint(ccp(0,0)); it says "Thread 1: EXC_BAD_ACCESS (code=2, adress=0x0)
Does anyone know why this happens and how to fix it?
Many thanks.
Ps: i'm using xcode, the latest cocos2d-x release and the iPhone simulator
Edit:
Using breakpoints i checked where things go bad while loading the tilemap.
on the line tileMap = CCTMXTiledMap::create(map);
my variable map is still fine
but on line tileMap->setAnchorPoint(ccp(0,0));
it is suddenly corrupted (most of the time)
It sounds like you're returning a char* string created on the stack, which means the memory may or may not be corrupted, depending on circumstances, moon phases, and what not.
So the question is: How is getLevel defined and what does it do (post the code)?
If you do something like this:
const char* LevelManager::getLevel(int level)
{
char* levelName = "default.tmx";
return levelName;
}
…then that's going to be the culprit. The levelName variable is created on the stack, no memory (on the heap) is allocated for it. The levelName variable and the memory it points to become invalid as soon as the method returns.
Hence when the method leaves this area of memory where levelName points to can be allocated by other parts of the program or other method's stack memory. Whatever is in that area of memory may still be the string, or it may be (partially) overridden by other bits and bytes.
PS: Your exception handling code is …. well it shows a lack of understanding what exception handling does, how to use it and especially when. I hope these are just remnants of trying to get to the bottom of the issue, otherwise get rid of it. I recommend reading a tutorial and introductions on C++ exception handling if you want to continue to use exceptions. Especially something like (map != NULL) should be an assertion, not an exception.
I fixed it.
const char* was to blame.
When returning my map as a char * it worked flawless.
const char *levelFileName = level.attribute("file").value();
char *levelChar = new char[strlen(levelFileName) + 1];
std:: strcpy (levelChar, levelFileName);
return levelChar;
Thats how i now return the map.