jetty
jetty

Reputation: 859

Value getting changed after end of function

I am trying to set data which needs to be used in another file (layer) of the application. During debugging , I see that the value gets correctly set for the first time . But when I try to use this set variable after the function , the value is changed. I think the memory is getting released causing the variable to reset . Can anyone please help me with what I am trying to do.

void SetExpectedTabsData(_In_ PCWSTR tabUrls[], _In_ PCWSTR tabTitles[], _In_ UINT tabsCount, _In_ FakeCourier* courier)
{
    wchar_t jsonPerTab[256];
    wchar_t tabsDataJSON[c_jsonTabDataSize];
    // tabsDataJSON should be large enough to hold any data.
    StringCchPrintf(tabsDataJSON, c_jsonTabDataSize, L"\"tabs\":[");
    bool isActiveTab = true;
    // tabId starts from 1 and the tabIndex starts with 0. Manipulated the json string generation accordingly.
    for (unsigned int i = 1; i <= tabsCount; ++i)
    {
        StringCchPrintf(jsonPerTab, ARRAYSIZE(jsonPerTab), L"{\"id\":%i,\"index\":%i,\"windowId\":1,\"active\":%s,\"status\":\"complete\",\"title\":\"%s\",\"url\":\"%s\"}", i, (i - 1), isActiveTab ? L"true" : L"false", tabTitles[i - 1], tabUrls[i - 1]);
        StringCchCat(tabsDataJSON, c_jsonTabDataSize, jsonPerTab);
        isActiveTab = false;
        if (i != tabsCount)
        {
            StringCchCat(tabsDataJSON, c_jsonTabDataSize, L",");
        }
    }
    StringCchCat(tabsDataJSON, c_jsonTabDataSize, L"],");
    VERIFY_SUCCEEDED(courier->SetExpectedTabsData(tabsDataJSON));
}

The courier file where the data needs to be set is as

HRESULT FakeCourier::SetExpectedTabsData(_In_ wchar_t* tabsData)
{
  m_tabsData = tabsData;
  return S_OK;
}

Please suggest the correct approach to do this.

Upvotes: 0

Views: 46

Answers (1)

Ilya
Ilya

Reputation: 4689

The variable tabsDataJSON is local in the function SetExpectedTabsData, so it can be overwritten after finishing of this function. And since it can happen, it happens.

When you call FakeCourier::SetExpectedTabsData(tabsDataJSON), this function just remembers pointer to that local variable tabsDataJSON. But right after finishing of the function SetExpectedTabsData this pointer becomes invalid.

To fix it you need to modify the function FakeCourier::SetExpectedTabsData: replace copying of the pointer be copying of the pointed data. Since your m_tabsData is a wchar_t*, just allocate this string and copy the data from tabsData into m_tabsData (read about wcsncpy and similar functions).

Try something like this:

HRESULT FakeCourier::SetExpectedTabsData(_In_ wchar_t* tabsData)
{
  const size_t len = wcslen(tabsData);
  if (m_tabsData)
    delete m_tabsData;
  m_tabsData = new wchar_t[len + 1];
  wcsncpy(m_tabsData, tabsData, len + 1);
  return S_OK;
}

And also you need to free this memory in the destructor of the FakeCourier (to avoid memory leak). And to initialize m_tabsData in the constructor (m_tabsData = 0;)

Upvotes: 1

Related Questions