visual-c++mfcfreecode-analysischm

Code analysis C26408 — Replacing the m_pszHelpFilePath variable in InitInstance


In my application's InitInstance function, I have the following code to rewrite the location of the CHM Help Documentation:

CString strHelp = GetProgramPath();
strHelp += _T("MeetSchedAssist.CHM");
free((void*)m_pszHelpFilePath);
m_pszHelpFilePath = _tcsdup(strHelp);

It is all functional but it gives me a code analysis warning:

C26408 Avoid malloc() and free(), prefer the nothrow version of new with delete (r.10).


When you look at the official documentation for m_pszHelpFilePath it does state:

If you assign a value to m_pszHelpFilePath, it must be dynamically allocated on the heap. The CWinApp destructor calls free( ) with this pointer. You many want to use the _tcsdup( ) run-time library function to do the allocating. Also, free the memory associated with the current pointer before assigning a new value.

Is it possible to rewrite this code to avoid the code analysis warning, or must I add a __pragma?


Solution

  • Technically, you can take advantage of the fact that new / delete map to usual malloc/free by default in Visual C++, and just go ahead and replace. The portability won't suffer much as MFC is not portable anyway. Sure you can use unique_ptr<TCHAR[]> instead of direct new / delete, like this:

    CString strHelp = GetProgramPath();
    strHelp += _T("MeetSchedAssist.CHM");
    std::unique_ptr<TCHAR[]> str_old(m_pszHelpFilePath);
    auto str_new = std::make_unique<TCHAR[]>(strHelp.GetLength() + 1);
    _tcscpy_s(str_new.get(), strHelp.GetLength() + 1, strHelp.GetString());
    m_pszHelpFilePath = str_new.release();
    str_old.reset();
    

    For robustness for replaced new operator, and for least surprise principle, you should keep free / strdup.

    If you replace multiple of those CWinApp strings, suggest writing a function for them, so that there's a single place with free / strdup with suppressed warnings.