Проблема размера массива wchar_t с wcscpy_s - PullRequest
0 голосов
/ 12 июня 2018

Я запутался с проблемой размера.Выполнение следующего кода вызывает исключение во время выполнения.В частности, кажется, что он появляется в конце, и текст все равно будет вставлен с успехом.Из-за моих ограниченных навыков я не могу четко истолковать исключение.Это началось, когда я решил использовать функцию 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 голосов
/ 12 июня 2018

wcscpy_s() ожидает счетчик CHARACTER, но вместо этого вы передаете ему счетчик BYTE.В Windows sizeof(wchar_t) составляет 2 байта.

Вам необходим счетчик BYTE при выделении памяти для буфера буфера обмена (который в вашем примере потребует 14 байтов), но так как вы передаете счетчик BYTE как CHARACTERсчитая до wcscpy_s(), вы говорите, что буфер буфера обмена может содержать до 14 wchar_t элементов, тогда как на самом деле он может содержать только 7. Вы даете wcscpy_s() разрешение выходить за пределы буфера буфера обмена (например, если он хочет предварительно заполнить буферную память, а затем заполнить ее реальными символами). Это может привести к повреждению стека вызовов , что может легко вызвать исключение при выходе из main().

Вам необходимо передать wcscpy_s() максимальное количество символов, которые может содержать буфер буфера обмена.,Не максимальное количество байтов, которое он может содержать.

Вы можете сделать это, разделив iSize на sizeof(wchar_t), например:

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

В качестве альтернативы, поскольку вы используете точный BYTEразмер исходного массива для выделения буфера буфера обмена, вы можете использовать _countof(), чтобы получить количество символов в массиве (вы не можете передать выделенный буфер буфера обмена _countof()), например:

wcscpy_s(wpchData, _countof(wcSource), wcSource);

В качестве альтернативы вы можете использовать wsclen() вместо, например:

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);
...