|
If I add any thing to entry point I cant compile your code else it doesnt any problem.(Visual sutdio2008)
|
|
|
|
|
Thanks Hamid,
If I add main to entry point, I can build, but when run it has errors.
regards,
George
|
|
|
|
|
But I get a linker error and I cant comnpile it.
|
|
|
|
|
Sorry, Hamid!
There is no link error for me and I can not reproduce it. I only have runtime error.
regards,
George
|
|
|
|
|
It was interest for me your question.
|
|
|
|
|
Thanks Hamid,
I like to discuss with you. But for this case, we'd better be able to reproduce the situation by others, right?
regards,
George
|
|
|
|
|
I never tested this problem previous I think I must tell you thanks for your help.
|
|
|
|
|
It is ok, Hamid!
We are helping each other.
regards,
George
|
|
|
|
|
By the way I have a different question did you study in psychology?
|
|
|
|
|
Hi,
I'm seeing a strange problem; I learned to program in C and compiled with gcc, and back when I used to use character arrays all the time, I always needed to free memory. For instance:
char *a = new char(100);
Before the function was out, I would need to free it:
free(a);
Now I'm working on an MFC app (using VC++ .NET 2005) and it seems to crash when I try to free the memory (in this same situation; where I've created a character array, used it, then need to delete it a few lines later). Is allocation handled differently with the newer C++ compilers?
Thanks!
KR
|
|
|
|
|
One point I can say is when using new , you use delete . And when using malloc , use free . What was the message when the application crashed?
|
|
|
|
|
It does the same thing whether I use delete or free, and there's no message, it just crashes somewhere in free.c. If I set the char array to a static size then I see no issues, it's only when I allocate memory for it. Then, regardless of whether I delete or don't delete, my program starts showing very odd behavior.
Here's the actual code:
#ifdef _UNICODE
CString strText = (This piece of code returns a CStringA from the back-end of my program)
if (strText.GetLength() <= 0)
return false;
char *convertThis = new char(strText.GetLength());
sprintf(convertThis, "%s", strText);
int nLen = lstrlenA(convertThis);
BSTR unicodeStr = SysAllocStringLen(NULL, nLen);
MultiByteToWideChar(CP_ACP, 0, convertThis, nLen, unicodeStr, nLen);
m_EditControl.SetWindowText(unicodeStr);
SysFreeString(unicodeStr);
delete convertThis;
#else
Everything works fine if I set convertThis to a static size. If I allocate, everything goes haywire whether I free memory or not, but especially quickly if I free memory.
KR
|
|
|
|
|
I see a few problems here...
#ifdef _UNICODE
CString strText = (This piece of code returns a CStringA from the back-end of my program) <font color="Red"><-- assigning a CStringA to a CString shouldn't compile - mismatched types</font>
if (strText.GetLength() <= 0)
return false;
char *convertThis = new char(strText.GetLength()); <font color="Red"><-- what about +1 for the null terminator?</font>
sprintf(convertThis, "%s", strText); <font color="Red"><-- _UNICODE is defined, so strText is a wchar_t type string - this copy to char is invalid</font>
int nLen = lstrlenA(convertThis);
BSTR unicodeStr = SysAllocStringLen(NULL, nLen); <font color="Red"><-- why BSTR? A wchar_t array is the appropriate type for unicode - MultiByteToWideChar() takes a LPWSTR, not a BSTR</font>
MultiByteToWideChar(CP_ACP, 0, convertThis, nLen, unicodeStr, nLen); <font color="Red"><-- The original CString was already Unicode...this conversion is unnecessary</font>
m_EditControl.SetWindowText(unicodeStr);
SysFreeString(unicodeStr);
delete convertThis;
#else If you just need to convert a CStringA to a CString, you can just do this:
<font color="Green">
CStringA strText = (This piece of code returns a CStringA from the back-end of my program)
CString strTextGeneric(strText);
m_EditControl.SetWindowText(strTextGeneric);
<font color="Green"> Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Unfortunately it's not that simple, the string type is a CStringW yes but the characters are actually in CStringA format so the conversion is necessary. The compiler doesn't realize that it's a CStringA because the project settings for my front-end project define _UNICODE but my backend (a series of separate projects and libraries) is all in MBCS, which is where the function comes from (i.e. lots of text without the _T macro). I can't change that - the backend is going to return a multi-byte CString no matter what I do, but the program and compiler think it's of type CStringW because of my front-end project settings.
sprintf works correctly because of the above reason (even though CString type is a wide character array, the data inside is actually MBCS format).
I need the BSTR because MultiByteToWideChar will not compile if I define the type as wchar_t, and SetWindowText would require a conversion if I defined the type as LPWSTR. If I use BSTR I can do what I did and it works, if I don't use a BSTR additional steps are required.
I have tried:
CStringA strText = (CStringA)function();
CString strTextGeneric(strText);
m_EditControl.SetWindowText(strTextGeneric);
But that does not work, it just returns some garbled crud, probably because it thinks that the piece of code that returns CStringA is actually a CStringW.
But you're right about the +1 for null terminator, I did forget about that. However it doesn't help if I add that, it still crashes unless I define convertThis as a char array with a static length.
KR
|
|
|
|
|
KellyR wrote: I need the BSTR because MultiByteToWideChar will not compile if I define the type as wchar_t, and SetWindowText would require a conversion if I defined the type as LPWSTR
That doesn't make sense. A BSTR is a WCHAR*, which is a wchar_t*
Using a generic string type, implemented as a template no less, on a back end that could be used
by a front end with a different type....bummer. I don't know what to say about that
Regardless, I suppose using the square brackets and leaving room for null terminators should
help a lot.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: Using a generic string type, implemented as a template no less, on a back end that could be used
by a front end with a different type....bummer. I don't know what to say about that
It's horrible.
Mark Salsbery wrote: Regardless, I suppose using the square brackets and leaving room for null terminators should
help a lot.
Everything seems to work now with square brackets and with the +1 for null terminator. Thanks!
KR
|
|
|
|
|
KellyR wrote: It's horrible.
Heh - it's painful to think about
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
KellyR wrote: Now I'm working on an MFC app (using VC++ .NET 2005) and it seems to crash when I try to free the memory
Could it be that you changed a to point to a different address? For example:
char *a = new char[100];
a = a + 1;
a = "Hello";
delete [] a; Or that free() does not go with new ?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Use square brackets when allocating arrays with new , not round ones: it looks like you allocating a single char initialised to ASCII 100, then treating it as an array. This is a buffer overrun and you're probably corrupting the stack.
If you use new match it with a delete . If you use new ??[] match it with a delete [] . If you use malloc match it with a free . Don't mix and match.
Steve
|
|
|
|
|
|
There's also the problem that
char *a = new char(100); does not allocate an array. It allocates one char and initializes it to 100. You want
char *a = new char[100];
|
|
|
|
|
I am using Ultimate TCP/IP to ping an address. worked great until I put it into a seperate thread. I believe I have the pointers right to execute the class, but when the parent class gets the call from the return it is always OnTimout.
I must be doing something stupid here....
void CBinDlg::StartPinger(void)
{
CWinThread* pWThread = AfxBeginThread(PingAddress, this);
}
UINT PingAddress(LPVOID pParam)
{
CBinDlg* pDlg = (CBinDlg*)pParam;
pDlg->icmp.SetDoLookup(false);
pDlg->icmp.SetMaxTimeOuts(1);
pDlg->icmp.Ping( "10.0.2.60" , 1500, 32, 2);
return 0;
}
|
|
|
|
|
I don't know anything about Ultimate TCP/IP but you've passed a pointer to a dialog (based on the class name) to a worker thread. Worker threads don't have message pumps so your pDlg is not going to do anything.
Judy
|
|
|
|
|
Well phooey! back to the drawing board.
Thank you
|
|
|
|
|
Rhymhoont wrote: pDlg->icmp.SetDoLookup(false);
pDlg->icmp.SetMaxTimeOuts(1);
pDlg->icmp.Ping( "10.0.2.60" , 1500, 32, 2);
You need to put these three statements back in the primary thread (since they interact with the UI) and change PingAddress() to:
UINT PingAddress( LPVOID pParam )
{
CBinDlg *pDlg = (CBinDlg *) pParam;
return pDlg->PingAddress();
}
UINT CBinDlg::PingAddress( void )
{
PostMessage(some_user_defined_message);
return 0;
}
LRESULT CBinDlg::OnPostedMessage( WPARAM, LPARAM )
{
icmp.SetDoLookup(false);
icmp.SetMaxTimeOuts(1);
icmp.Ping("10.0.2.60" , 1500, 32, 2);
return 0;
}
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|