views:

80

answers:

3

I'm not sure what is the root cause for getting such error(Heap Corruption) from the below code. When i step through the program, the TCHAR value is properly allocated and copied to the clipboard data. However, it crash when it proceed to SetClipboardData(...).

Can any guru help to spot the error?

Thanks in advance.

Error Dialog:

Heap block at 04A781C0 modified at 04A78282 past requested size of ba Windows has triggered a breakpoint in V4.exe.

This may be due to a corruption of the heap, which indicates a bug in V4.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while V4.exe has focus.

The output window may have more diagnostic information. The program '[10840] V4.exe: Native' has exited with code 0 (0x0).

Code:

    int nCount = m_ListBox.GetCount();
    CString szTemp, szText;
    for(int i=0; i<nCount; i++)
    {
        m_ListBox.GetText(i, szTemp);
        szText = szText + _T("\n") + szTemp;
    }
    if(OpenClipboard())
    {
        EmptyClipboard();
        HGLOBAL hClipboardData;
        size_t size = (szText.GetLength()+1) * sizeof(TCHAR);
        hClipboardData = GlobalAlloc(NULL, size);
        TCHAR* pchData = (TCHAR*)GlobalLock(hClipboardData);
        _tcscpy_s(pchData, size, LPCTSTR(szText));
#ifdef _UNICODE
        SetClipboardData(CF_UNICODETEXT, hClipboardData);  //--> crash here
#else
        SetClipboardData(CF_TEXT, hClipboardData);
#endif
        GlobalUnlock(hClipboardData);
        CloseClipboard();
    }

List Box data:

John Smith  1978  
Angelina    1975  
Brad Pitt   1950  
A: 

Following is the quote from the MSDN for SetClipboardData:

If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail.

Since you are passing NULL to OpenClipboard, SetClipboardData is failing.

Naveen
+4  A: 
_tcscpy_s(pchData, size, LPCTSTR(szText)); 

For Unicode wcscpy_s function, size parameter is size in words, and you pass size in bytes. This may cause memory corruption, because wcscpy_s fills all the buffer with 0xFD prior to copying, in order to catch such errors. (thanks to sharptooth for exact information).

Alex Farber
+1, except that according to http://msdn.microsoft.com/en-us/library/td1esda9(VS.80).aspx it doesn't pad to the end, but rather fills all the buffer with 0xFD prior to copying.
sharptooth
Cool... It works after i replaced _tcscpy_s with memcpy.
wengseng
Thanks for your help, Alex.
wengseng
A: 

Call GlobalUnlock(hClipboardData); before the call to SetClipboardData(CF_UNICODETEXT, hClipboardData);

Tassos