I am having an issue std::string assignment with the below code in VS2019, where it is working fine in VS2015. I am using Visual Studio 2019 (v142) as Platform Toolset in VS2019 and Visual Studio 2015 (v140) as Platform Toolset in VS2015.
class Test
{
public:
Test()
{
m_DisplayName = "";
m_Type = "";
}
std::string m_DisplayName;
std::string m_Type;
};
void CMFCApplication2Dlg::TestFunction()
{
// Sample Data setting in vector
std::vector<Test> vTest;
Test obj;
obj.m_DisplayName = "Nam1gd";
obj.m_Type = "t1";
vTest.emplace_back(obj);
Test obj2;
obj2.m_DisplayName = "Nam2";
obj2.m_Type = "t2";
vTest.emplace_back(obj2);
VARIANT vtResult_o;
VariantInit(&vtResult_o);
vtResult_o.vt = VT_ARRAY | VT_UI1;
int usrCount = vTest.size();
ULONG nBufferSize = usrCount * sizeof(Test);
// Define a safe array of usrCount Item and Starting index as 0
SAFEARRAYBOUND safeBounds = { nBufferSize, 0 };
//Create the Safe Array passing it the bounds
SAFEARRAY* pSafeArray = SafeArrayCreate(VT_UI1, 1, &safeBounds);
Test* vTestArray = nullptr;
SafeArrayAccessData(pSafeArray, (void**)&vTestArray);
// Data setting to Safe array
for (int nIdx = 0; nIdx < usrCount; nIdx++)
{
// ******VALUES ASSIGNING CORRECTLY in VS 2015 ******/
// ******JUNK VALUE COMES IN THIS ASSIGNMENT in VS 2019 ******/
vTestArray[nIdx].m_DisplayName = vTest[nIdx].m_DisplayName;
vTestArray[nIdx].m_Type = vTest[nIdx].m_Type;
}
/* decrement the lock count*/
SafeArrayUnaccessData(pSafeArray);
vtResult_o.parray = pSafeArray;
}
Since the string value in the vTest[nIdx].m_DisplayName
is small it is stored in the small buffer in s._Bx._Buf
. In VS2015 while assigning, the small buffer in the source string is copied to the destination string's small buffer.
for (int nIdx = 0; nIdx < usrCount; nIdx++)
{
// ******VALUES ASSIGNING CORRECTLY in VS 2015 ******/
// ******JUNK VALUE COMES IN THIS ASSIGNMENT in VS 2019 ******/
vTestArray[nIdx].m_DisplayName = vTest[nIdx].m_DisplayName;
vTestArray[nIdx].m_Type = vTest[nIdx].m_Type;
}
However, in VS2019, it is observed that the during assignment the destination's buffer (
s._Bx._Buf
) is updated with junk value and the actual value is updated to the heap s._Bx._ptr
.
Ideally since s._Bx
is a union either the s._Bx._Buf
or s._Bx._ptr
should be present. Please find the image below.
[Workaround]
However if I do a std::string casting in VS2019 it is assigning the std::string's small buffer in the source to the small buffer in the destination.
for (int nIdx = 0; nIdx < usrCount; nIdx++)
{
vTestArray[nIdx].m_DisplayName =(std::string)(vTest[nIdx].m_DisplayName);
vTestArray[nIdx].m_Type = (std::string)(vTest[nIdx].m_Type);
}
I will appreciate if some one can help me to understand why this difference in VS2015 and VS2019!