Kama

Hi,

I have a function in VS-6 which displays Helzo. (Project settings I changed in VS-6 are: In C++ tab the Warning level is set to "Level4" and Debug info as " Program Database")

void CVCTempDlg::OnOK()
{
char* pChar;
pChar = "Hello";
*(pChar+3) = 'z';
AfxMessageBox(pChar);

}

When I try to use the same function in Visual Studio.Net 2005 it compiles fine but throws an exception during run time.

void CtempDlg::OnBnClickedOk()

{ char* pChar;
pChar = "Hello";
*(pChar+3) = 'z';
AfxMessageBox(pChar);
}

I tried the following : IsBadWritePtr, memncpy, functions to set the 3rd char to Z, but no use.

Thanks in advance.

Kama




Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Marius Bancila

Are you sure is related to this piece of code

I suppose this is not the exact code you have, simply because what you do there doesn't make sense. Can you post the real code please






Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Kama

We have our own function to trim the spaces. The following is the code to it. It works in VS6 but not in VS2005

LPSTR RTrim( LPSTR lpsz )
{
char* pChar;

ASSERT(lpsz && AfxIsValidString(lpsz, -1));
int i = strlen(lpsz);

pChar = lpsz + strlen( lpsz ) - 1;

while (pChar >= lpsz && *pChar == ' ')
*pChar-- = 0;

return lpsz;
}






Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Mike Danes

It crashes because you are changing a string that is supposed to be constant. VC 2005 places strings like "Hello" in a readonly section so when you try to replace the fourth character with z you get an access violation.





Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Kama

Thanks for the reply. The objective of this function is to get the spaces chopped at the right

Eg: if I pass "a " it should result in "a"

if I pass "abc " it should result in "abc".

if I pass "abcd" it should simply return "abcd"

I can pass any string to funcion. As I said we are migrating our big application from VC6 to VC8. This function is called from may different function. We can rewrite everything usin CString but the testing effort is huge, as there is a lot of impact on the product.

Any solutions to this will be a great help.






Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Mike Danes

The RTrim function is correct but if you pass to it a pointer to a string literal and that string contains spaces at the end it will crash. The best thing to do is to avoid having string literals with spaces at the end. If that's not possible then you need to detect if the memory is readonly.

One way to do this is to use IsBadWritePtr

if (IsBadWritePtr(lpsz))

return lpsz;

However IsBadWritePtr has some issues and it use is strongly discouraged so the remaining option is to use VirtualQuery (which may be much slower):

MEMORY_BASIC_INFORMATION info;

VirtualQuery(lpsz, &info, sizeof(info));

if (info.Protect & PAGE_READONLY)

return lpsz;

I looked for an option to stop the compiler making string literals readonly but I cannot find such I thing. Anyway it's not a good idea to modify such strings.





Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Andrei Errapart

No rewrite needed. Just find the places which use string literals:

char* const_string = "ah ah ah ";
RTrim(const_string);
std::cout << const_string << endl;

and substitute them with:

char* nonconst_string = strdup("ah ah ah ");
RTrim(nonconst_string);
std::cout << nonconst_string << endl;
free(nonconst_string);





Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Marius Bancila

The code bellow trims the spaces on the left and right:

void trim_left_right(string& str)
{
string::size_type pos = str.find_last_not_of(' ');
if(pos != string::npos) {
str.erase(pos + 1);
pos = str.find_first_not_of(' ');
if(pos != string::npos) str.erase(0, pos);
}
else str.erase(str.begin(), str.end());
}






Re: Visual C++ Language Char* issue on Migrating from VC6 to VC8 (2005)

Kama

Thank you all for your help. I appreciate it. I am able to doa workaround solution using _strdup.