Memory reference scope issue: Variable value getting reset, How to Assign value to LPCWSTR?

480 Views Asked by At

I am a beginner cpp programmer. I am converting string value to LPCWSTR. When i am trying to access this value, it is giving a null value. Please check this code attached below. I think this is because of memory reference value is clearing out after the scope of the variable.

std::wstring string2wString(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

void main(){
    string str1,str2,str3;
    wstring wStr1;
    LPCWSTR lpStr1[MAX_PATH];
    int index=0;
    for(int i=0;i<iLimit;i++)
    {
        str1="String 1";
        //do operations
        for(int j=0;j<jLimit;j++)
        {
            // do operations
            str2=" String 2";
            str3= str1+str2;
            wStr1= string2wString(str3); //converting to wstring
            lpStr1[index]=wStr1.c_str();
            index++
        }
    }
    cout << lpStr1[0] << endl;
}

Please help me to resolve this issue.

4

There are 4 best solutions below

1
On BEST ANSWER

The pointer returned by wStr1.c_str() may become invalid when wStr1 is later modified.

The best fix is to stick to C++ types:

std::wstring strings[MAX_PATH];

// ...
MultiByteToWideChar(CP_ACP, 0, str3.c_str(), slength, buf, len);
strings[index] = buf;
delete[] buf;
// ...

or, you could postpone deleting the buffer and just use it in your array:

LPCWSTR lpStr1[MAX_PATH];
// ...
wchar_t* buf = new wchar_t[len];   
MultiByteToWideChar(CP_ACP, 0, str3.c_str(), slength, buf, len);
lpStr1[index] = buf;
3
On

There are a few problems here:

  • LPCWSTR lpStr1[MAX_PATH]; is defining an array of pointers to const wchar_t, not an array of const wchar_t as you no doubt intend.
  • lpStr1[index]=wStr1.c_str(); is storing the pointer to the temporary buffer returned by c_str(). This does not copy the string into lpStr[index].
  • I'm not sure what iLimit and jLimit are, but I don't see what those loops are intending to accomplish if you really only want to convert a string value to a wide character array.
0
On

I'd suggest using the following routine for UNICODE conversion:

wstring AsciiToUtf16(const string & str)
{
   if (str.empty())
      return wstring();

   size_t charsNeeded = ::MultiByteToWideChar(CP_ACP, 0, 
      str.data(), (int)str.size(), NULL, 0);
   if (charsNeeded == 0)
      throw runtime_error("Failed converting ASCII string to UTF-16");

   vector<wchar_t> buffer(charsNeeded);
   int charsConverted = ::MultiByteToWideChar(CP_ACP, 0, 
      str.data(), (int)str.size(), &buffer[0], buffer.size());
   if (charsConverted == 0)
      throw runtime_error("Failed converting ASCII string to UTF-16");

   return wstring(&buffer[0], charsConverted);
}
0
On

Why not follow this:

C++ Convert string (or char*) to wstring (or wchar_t*)

and forget the LPCWSTR altogether?