0

Suppose I have this:

LPTSTR MyString = _T("A string"); 
void SomeFunction(LPCWSTR param);

I can use one of the ATL conversion macros, CT2CW, and the function works as expected:

SomeFunction(CT2CW(MyString));

However, if I have something like this:

LPWSTR WString = CT2CW(MyString); // or CT2W, it doesn't matter

Now WString doesn't contain what I would expect it to; it just appears to contain garbage. I am sure this is some funky pointer business, but I am stumped.

quantumSoup
  • 27,197
  • 9
  • 43
  • 57
  • 1
    Why do you monkey around with `TCHAR` **at all**? Read http://stackoverflow.com/questions/234365/is-tchar-still-relevant/3002494#3002494 Anyway, in what way does `WString` not contain what you expected? Is such the case in the next line, or only after returning? – Deduplicator Jan 20 '15 at 01:21
  • @Deduplicator I am modifying a huge existing code base. I can't do anything about it unless I redo and retest tons of code for no good reason. `WString` contains completely garbled data. – quantumSoup Jan 20 '15 at 01:33
  • Well, I wish you luck and perseverence than. There are always those cases... – Deduplicator Jan 20 '15 at 04:01

1 Answers1

3

The memory used to store the string is freed when the CT2CW object is destroyed.

In fact, the MSDN page you linked to already mentions this exact problem.

In SomeFunction(CT2CW(MyString));, the temporary CT2CW object is not destroyed until the entire statement, including the function call, has executed - see "Life span of temporary arguments?".

In LPWSTR WString = CT2CW(MyString);, the temporary CT2CW object is destroyed when the entire statement has executed. That means that after this statement executes, WString points to memory that has been freed.

The solution, as already mentioned in the MSDN article you linked to, is to use a local variable instead of a temporary object:

CT2CW WString(MyString);

Local variables are not destroyed until the end of their scope.

Community
  • 1
  • 1
user253751
  • 57,427
  • 7
  • 48
  • 90
  • Thanks. But now when I try `LPTSTR MyString = _T("A string"); LPWSTR WString; CT2W WString(MyString);`, it gives me this error `"error C2040: 'WString' : 'ATL::CA2W' differs in levels of indirection from 'LPWSTR'"`. I assume *this* is a pointer problem? – quantumSoup Jan 20 '15 at 01:53
  • 1
    @quantumSoup why are you trying to define `WString` twice with different types? (`CT2W` can be implicitly converted to `LPWSTR` already, if that's what the confusion is from) – user253751 Jan 20 '15 at 02:04
  • It all makes sense now. I have not coded in C++ since college for assignments, and I am overthinking it. Thanks. – quantumSoup Jan 20 '15 at 02:05