|
You are also missing the element count argument in DisplayProp
char PurchaseProperty::DisplayProp(char PropNameArray[], int count)
{
int index;
for(index = 0; index < count; index++)
{
cout << PropNameArray[index];
}
return 0;
}
No point supplying it if you don't use it.
|
|
|
|
|
Hi all,
I am writing an app using C++, Visual Studio 2008 and Qt. I have been working on a certain section of code, and i have it working now without any problems. That is in debug mode. When i compiled it in release mode the other day, the app crashed (access violation) when i performed a certain action (selecting an item from a combo box). This did not happen in debug mode, and it happens consistently whenever i switch back to compiling in release.
My app is similar to Spy++ or Winspector and it uses a hook to monitor other window's messages. It does this by injecting a DLL in other processes. When i first tried to debug the crash in VS, the stack trace included the hook procedure and it even showed me the code (which is strangle because the DLL should have been built without symbols too). It was indicating that the crash was around the call to CallNextHookEx.
But i don't think it has anything to do with that because when i commented out the hook code, the crash still happened.
I suspect it is due to memory corruption, but i don't know how to be sure. Basically, i am asking for any tips on how to debug such a situation. I cannot step through the code as there are no symbols in release mode, and the DLLs in other processes only makes debugging harder.
Since i have no idea what could be causing the crash, i will not post any code. However, i will upload the entire source (to my SourceForge site) and post a link to it so that you can browse though it if you like.
If it helps, the assembly where the crash happened is:
004320EE mov edx,dword ptr [eax+ecx*4+14h]
[ Window Detective] - Windows UI spy utility
modified on Thursday, December 9, 2010 5:50 PM
|
|
|
|
|
1.) you can compile a release with the option 'generate debug info' too.
2.) insert beeps or log-infos to localize the buggy code position.
3.) initialize all memory allocated by zero also static and local member.
4.) enshure you don't write beyond allocated memory.
5.) the debug version: checks memory (allocating more than neccessary and fill them with special values). also debug: checks the stack integrity.
6.) use the same compiler/linker options for release same as debug.
7.) turn on multithreading option.
|
|
|
|
|
you could tell the linker to produce a link map, then use that to identify which function contains 004320EE mov edx,dword ptr [eax+ecx*4+14h]
|
|
|
|
|
How would i do that
By the way, it is ecx that contains a rather large number, which is causing the expression to access invalid memory. So i imagine that ecx should normally contain a valid value.
|
|
|
|
|
based on the virtual address.
|
|
|
|
|
Sorry, i still don't know what you are talking about. You seem to be saying that there is a way to find the function which that line of code is in. While i understand that it may technically be possible, i have no idea how to do it.
btw, thanks to everyone else who replied.
|
|
|
|
|
research this[^]
XTAL256 wrote: thanks to everyone else
No thanks then.
|
|
|
|
|
Well, i was going to thank you once you clarified your previous post. But since you gave me the lmgtfy response, i don't think i will . Just kidding.
|
|
|
|
|
Please read this: Surviving the release version[^]
It was ever thus, the Neophiles will always rush out and get 'The Latest Thing' at a high price and with all the inherent faults - Dalek Dave.
|
|
|
|
|
fyi, i found the problem. I stupidly forgot to return a value from a function. I only just picked it up then when the compiler told me that "not all control paths return a value". I guess i missed that warning previously.
|
|
|
|
|
I have seen the term Fixed_32 for a data item with MSB = 1 and LSB = 1/2**31 ;
Max = 1.0 and Min = -1.0 with units of semicircles (used for Latitude and Longitude)
I did think this was a float to the IEEE-754 Floating-Point Representation.
However the 3rd party that is reading some data via a message structure cannot see the same value.
I mistaken the term Fixed_32 as a standard float but it is a 32 bit int in the message.
The scalling is:-
#define BEARING_SCALING 4.65661287307739E-10
typedef struct ReceiveMessage
{
unsigned int msgNumber;
int msgPosLat;
int msgPosLong;
unsigned int msgQuality;
}positionData
#define BEARING_SCALING 4.65661287307739E-10 However I get a crash when I try to load the value (the Latitude was declared as a double and I tried to cast to the int and vice versa.
Code:
double lat = 55.55;
positionData.msgPosLat = (int)(lat/(BEARING_SCALING * 180));
lat = (double)( positionData.msgPosLat) * BEARING_SCALING * 180;
What is going wrong please, is it the oder of casting or do I need to use fix point stuff?
|
|
|
|
|
I think it works like this:
the latitude in degrees ranges from -90 to +90 (and not -180 to +180).
the encoding used is 32-bit fixed integers with an implied scale factor, so the full range [-90,+90] gets mapped onto the full integer range.
So you want +90 represented by the largest positive 32-bit integer (which equals 2^31 minus one, or 0x7FFFFFFF), hence:
int fixed32(double lat) {
lat=lat/90.;
lat=lat*0x7FFFFFFF;
return (int)lat;
}
Notes:
1. this code will never return the minimum value (0x80000000). For -90 it results in 0x80000001 which is a consequence
of [-90,+90] being symmetric around zero, whereas the integer range [0x80000000, 0x7FFFFFFF] isn't.
2. I tend to avoid magic constants, such as the 4.65661287307739E-10 you had. I prefer to write them in a way that reveals what they stand for. Your value stems from 1.0/0x7FFFFFFF
3. I doubt the code you have shown would crash at all.
lat/(BEARING_SCALING * 180) will not exceed the acceptable range for integers (and your formula being wrong by a factor of 2 IMO only reassures this).
(positionData.msgPosLat) * BEARING_SCALING * 180) may incur an integer overflow (again due to the factor of 2), but normally those get swallowed.
So I expect if anything bombs, it must be the code that follows after you used these formulas, mainly the latitude going all the way up to +180.
|
|
|
|
|
Thanks Luc, the Longitude (-180 to +180) has the same scaling.
I can get the code running OK on Windwos but when ported to Unix (using a Gnu complier) the program bombs out.
Debuggin a bit limited hence the use of Windows for the development.
|
|
|
|
|
Andy202 wrote: the Longitude (-180 to +180) has the same scaling.
not sure what you are saying here. the longitude range has to cover 360 degrees (either -180 to +180 or 0 to +360), so it could be latitude uses the same scale factor, but then your opening statement (about MIN and MAX) isn't accurate for latitude.
OTOH if the scale factor is different for lat and lon, that would justify why the 180 (or 360) isn't incorporated in the magic constant.
Andy202 wrote: when ported to Unix (using a Gnu complier) the program bombs out.
A different compiler may generate different code, e.g. it could emit code that does check for overflows at run-time.
[ADDED] So far you have not specified where in the code it crashes. [/ADDED]
I can only suggest you:
1. include some logging statements so you can watch the numbers till the program crashes.
2. perform some unit tests (a simple loop over the range of interest should be easily implemented).
Taken together, that will clarify what goes on.
|
|
|
|
|
normally c-compilers cast from left to right (implicit). if yours don't - cast yourself (explicit):
positionData.msgPosLat = (int)(lat/(BEARING_SCALING * 180.0));
// (int)(double/(double*double))
AND
lat = ( (double)positionData.msgPosLat * (BEARING_SCALING * 180.0));
// (double*(double*double))
// hint: don't define twice (BEARING_SCALING)
have a nice day.
|
|
|
|
|
hi guys,,,
i'm a newbie in MFC so i'm need your advice to complete final project about identification signature. in this time i have problem about how to save image from picture box in MFC. this is my code used in MFC. this code not save image from picturebox. what's wrong with my code???
void SaveBitmapToFile( BYTE* pBitmapBits, LONG lWidth, LONG lHeight,WORD wBitsPerPixel, LPCTSTR lpszFileName );
void CSaveimageDlg::OnSave()
{
// TODO: Add your control notification handler code here
CDC *pDC = m_pic1.GetDC();
CDC dcMem1;
CRect rect;
m_pic1.GetClientRect(rect);
HDC hdc;
HBITMAP hBitmap = NULL;
BITMAP bm;
CBitmap Bitmap;
m_pic1.SetBitmap(Bitmap);
Bitmap.CreateBitmap(200 ,200,1,24,NULL);
m_bmpBitmap.GetBitmap(&bm);
//Bitmap.GetBitmap(&bm);
Bitmap.GetObject( sizeof( BITMAP ), &bm );
unsigned char *pData = new unsigned char [bm.bmHeight*bm.bmWidthBytes];
SaveBitmapToFile(pData,bm.bmHeight,bm.bmWidth,24,(LPCTSTR)_T("a.bmp"));
delete []pData;
}
void CSaveimageDlg::SaveBitmapToFile(BYTE *pBitmapBits, LONG lWidth, LONG lHeight, WORD wBitsPerPixel, LPCTSTR lpszFileName)
{
BITMAPINFOHEADER bmpInfoHeader = {0};
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biBitCount = wBitsPerPixel;
bmpInfoHeader.biClrImportant = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biCompression = BI_RGB;
bmpInfoHeader.biHeight = lHeight;
bmpInfoHeader.biWidth = lWidth;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biSizeImage = lWidth* lHeight * (wBitsPerPixel/8);
BITMAPFILEHEADER bfh = {0};
bfh.bfType=0x4D42;
bfh.bfType = 'B'+('M' << 8);
bfh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
bfh.bfSize = bfh.bfOffBits + bmpInfoHeader.biSizeImage;
HANDLE hFile = CreateFile( lpszFileName,GENERIC_WRITE, 0,NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
if( !hFile ) // return if error opening file
{
return;
}
DWORD dwWritten = 0;
WriteFile( hFile, &bfh, sizeof(bfh), &dwWritten , NULL );
WriteFile( hFile, &bmpInfoHeader, sizeof(bmpInfoHeader), &dwWritten, NULL );
WriteFile( hFile, pBitmapBits, bmpInfoHeader.biSizeImage, &dwWritten, NULL );
CloseHandle( hFile );
}
|
|
|
|
|
1.) width != byte_width! byte_width == (width*(bitsperpixel/8)+3)&~3 (4byte boundary)
2.) call GetBitmapBits to get the bitmap content before save.
have a nice day.
|
|
|
|
|
Hello
Try this.
http://www.ucancode.net/Visual_C_Codes/MFC-Example-CreateFile-WriteFile-save-memory-dc-bitmap-file.htm
instead of memdc, you can call your picture box dc.
Thanks
A. Gopinath.
|
|
|
|
|
thx for your answer sir..
but after i try the code, i can't find image c://temp.bmp.
can u tell me , how to the code work in MFC to save a image di picturebox.
my problem : i will load a image to picturebox in MFC then i'm want to save it.
can u give sample code about my problem??
Regard's
Johannes.
|
|
|
|
|
Thx sir..
but i dont understand..
Can you explain in detail the program...
Regard
Johannes
|
|
|
|
|
Hello
try by sending this hDC to save. I didn't tried this. check whether it is working or not.
HDC hDC=GetDC(GetDlgItem(IDC_PICTUREBOX); //------- id for your picture box.
Save...... (hDC, ...);
Thanks
A. Gopinath.
|
|
|
|
|
sir, i got a error.. "GetDC' : function does not take 1 parameters"
how about it??
|
|
|
|
|
Hello,
sorry for delay. instead of HDC you can use CClientDC. that will work.
Regards,
A. Gopinath.
|
|
|
|
|
hi
i defined an accelerator Ctrl+T to generate ID_TMPDLG. i put
ON_COMMAND(ID_TMPDLG, &Ct2App::OnTmpDlg)
but the function is not called. i tried to see whether to message for the accelerator is generated correctly and i tested it in:
BOOL Ct2App::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == 'T')
return CWinAppEx::PreTranslateMessage(pMsg);
return CWinAppEx::PreTranslateMessage(pMsg);
} by defining a break point, i realized that the line is hit and the message is produced correctly. but i don't know why the command ID_TMPDLG is not generated or received by the application. i tried to handle the command in another places like main frame and child view, but it didn't help and the command is not still generated or received. i don't know whether the accelerator message is not converted into the command or the message is lost somewhere.
what can i do?
thx
|
|
|
|
|