简体   繁体   中英

Strange Results when converting int to LPCTSTR with sstream

I have declared the following method to convert an integer to a LPCTSTR for use in an MFC application.

LPCTSTR CTCPServerDlg::Int32ToLPCTSTR(int i32) {
    std::wostringstream ss;
    ss << i32;
    LPCTSTR res = ss.str().c_str();
    MessageBox(ss.str().c_str()); // Correctly shows value.
    MessageBox(res); // Nothing shown.
    return res;
}

As commented above, the first message box correctly shows the integer I pass into the i32 parameter. The second messagebox displays nothing (or I presume invisible characters). When calling the function like so:

MessageBox(Int32ToLPCTSTR(3));

I get some strange character. I think it's a chinese symbol. I understand that Unicode and ANSI with different types in Windows can confuse the best of us, but the return value of ss.str().c_str() should assign properly to the LPCTSTR res variable I declare right? Furthermore, when attempting to insert the created LPCTSTR into a CEdit control, I get even more unknown chinese characters, all different from before.

Apologies if I am being stupid, help appreciated!

res is a dangling pointer. The str() function of wostringstream returns a new std::wstring by value. This means that it's a temporary.

The std::wstring function c_str() returns a pointer to the internal buffer of the string. That pointer is only valid as long as the string itself remains valid (and unmodified).

This together means that res becomes dangling as soon as its initialisation ends.

The entire interface of your function looks flawed. To return a LPCTSTR , it will have to allocate memory for the returned string. But this means you'll be returning a raw pointer to dynamically-allocated memory, which leads to leaks, double-deletion errors etc. Simply change your function to return a std::wstring (or _tstring if you really want to keep using TCHAR ). You can then obtain a LPCTSTR from it whenever necessary by calling c_str() .

Even better, I suggest you drop the use of TCHAR altogether. Are you ever going to build your application for single-byte character strings or multi-byte character strings? I'd assume not, in which case you can simply use std::wstring , wchar_t and the appropriate functions throughout, and make your life easier.

The string returned by ss.str() returned by value , and if you don't store it then it is temporary and will be destructed once the expression is done, leaving you with a pointer to a string that no longer exists. This will of course lead to undefined behavior when you try to dereference that stray pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM