Reputation: 718
I'm confused with a size issue. Running the following code throws an exception at runtime. Specifically it seems to appear at end, and the text still be pasted with success. Due to my limited skills I'm not able to interpret the exception clearly. It started when I decided to use the wcscpy_s function due to depreciation of wcscpy which worked fine in my noob program.
#define _CRT_SECURE_NO_WARNINGS
#include <afxwin.h>
int main() {
wchar_t wcSource[7] = L"Testeu"; // Throws an exception error. However, wcSource[8] doesn't
//wchar_t wcSource[9] = L"TestCopy"; // Runs fine
UINT iSize = sizeof(wcSource);
if (OpenClipboard(NULL)) {
EmptyClipboard();
HGLOBAL hClipboardData;
hClipboardData = GlobalAlloc(GMEM_DDESHARE, iSize);
wchar_t *wpchData;
wpchData = (wchar_t*)GlobalLock(hClipboardData);
//wcscpy(wpchData, wcSource); // Works fine
wcscpy_s(wpchData, iSize, wcSource);
GlobalUnlock(hClipboardData);
SetClipboardData(CF_UNICODETEXT, hClipboardData);
CloseClipboard();
}
return 0;
}
Upvotes: 1
Views: 3971
Reputation: 597590
wcscpy_s()
expects a CHARACTER count, but you are passing it a BYTE count instead. On Windows, sizeof(wchar_t)
is 2 bytes.
You need a BYTE count when allocating memory for the clipboard buffer (which in your example will require 14 bytes), but since you are passing the BYTE count as a CHARACTER count to wcscpy_s()
, you are telling it that the clipboard buffer can hold up to 14 wchar_t
elements, when in actuality it can hold only 7. You are giving wcscpy_s()
permission to go out of bounds of the clipboard buffer (for instance, if it wants to pre-fill the buffer memory before then filling it with actual characters). Doing so would corrupt the call stack, which could easily cause an exception when main()
exits.
You need to pass wcscpy_s()
the max number of CHARACTERS that the clipboard buffer can hold. Not the max number of BYTES it can hold.
You can do that by dividing iSize
by sizeof(wchar_t)
, eg:
wcscpy_s(wpchData, iSize / sizeof(wchar_t), wcSource);
Alternatively, since you are using the exact BYTE size of the source array to allocate the clipboard buffer, you can use _countof()
to get the number of CHARACTERS in the array (you cannot pass the allocated clipboard buffer to _countof()
), eg:
wcscpy_s(wpchData, _countof(wcSource), wcSource);
Alternatively, you can use wsclen()
instead, eg:
wchar_t wcSource[] = L"Testeu";
int iLen = wcslen(wcSource) + 1;
UINT iSize = iLen * sizeof(wchar_t);
...
hClipboardData = GlobalAlloc(GMEM_DDESHARE, iSize);
...
wcscpy_s(wpchData, iLen, wcSource);
Upvotes: 6