wcscpy_s

时间:2018-06-12 18:43:30

标签: c++ mfc copy clipboard wchar-t

我对尺寸问题感到困惑。运行以下代码会在运行时引发异常。具体来说,它似乎在最后出现,文本仍然粘贴成功。由于我的技能有限,我无法清楚地解释这个例外。 它开始于我决定使用 wcscpy_s 功能,因为 wcscpy 的折旧在我的noob程序中运行良好。

#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;
}

1 个答案:

答案 0 :(得分:5)

wcscpy_s()需要CHARACTER计数,但您传递的是BYTE计数。在Windows上,sizeof(wchar_t)为2个字节。

在为剪贴板缓冲区分配内存时需要BYTE计数(在您的示例中需要14个字节),但由于您将BYTE计数作为CHARACTER计数传递给wcscpy_s(),因此您告诉它剪贴板缓冲区最多可以容纳14个wchar_t个元素,实际上它只能容纳7个。你正在授予wcscpy_s()超出剪贴板缓冲区范围的权限(例如,如果它想要预填充缓冲存储器然后用实际字符填充它。 这样做会破坏调用堆栈,这会在main()退出时轻易导致异常。

您需要传递wcscpy_s()剪贴板缓冲区可容纳的最大CHARACTER数。不是它可以容纳的最大BYT数。

您可以将iSize除以sizeof(wchar_t),例如:

wcscpy_s(wpchData, iSize / sizeof(wchar_t), wcSource);

或者,由于您使用源数组的精确BYTE大小来分配剪贴板缓冲区,因此可以使用_countof()来获取数组中的CHARACTERS数(不能将分配的剪贴板缓冲区传递给{ {1}}),例如:

_countof()

或者,您可以改为使用wcscpy_s(wpchData, _countof(wcSource), wcSource); ,例如:

wsclen()