Unicode字符集项目的一个函数中的访问冲突写入位置

Access violation writing location in a function of Unicode character set project

我的项目从多字节字符集项目改为unicode字符集。所以有很多变量类型需要转换以匹配参数的类型。我创建了一个将 char[] 类型转换为 LPWSTR 的函数。下面是代码:

LPWSTR CharFunction::CharToLPWSTR(char charVariable[])
{
    LPWSTR returnVariable;
    MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, 2048);
    return returnVariable;
}

不过,有

Unhandled exception at 0x77a9007e in xxxx.exe: 0xC0000005: Access violation writing location 0x7712311e.

我发现第一次可以运行,但是第2次出现错误在

MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, 2048);

我花了 3 个小时调试,但没有运气。如果有人可以帮助我修复此错误,我将不胜感激。谢谢。

更新:

下面是声明变量并将值传递给函数的代码片段。

LPWSTR        g_szSystemIni;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
_splitpath_s(szModuleName_converted, drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, ext, _MAX_EXT );
lstrcpy(g_szSystemIni,charfunction.CharToLPWSTR(drive));
lstrcat(g_szSystemIni,charfunction.CharToLPWSTR(dir));

来自MSDN

Caution Using the MultiByteToWideChar function incorrectly can compromise the security of your application. Calling this function can easily cause a buffer overrun because the size of the input buffer indicated by lpMultiByteStr equals the number of bytes in the string, while the size of the output buffer indicated by lpWideCharStr equals the number of characters. To avoid a buffer overrun, your application must specify a buffer size appropriate for the data type the buffer receives.

确保您发送正确的值作为第 4 个和第 6 个参数。 第 4 个参数是缓冲区大小或第一个字符串中的字节数,最后一个参数是转换后的字符数。并检查输出指针是否有足够的内存。

在提供的代码中,您没有为 returnVariable 分配 space。

一个简单的 new 可以工作,但在您的情况下,这将导致更难解除分配机制。

LPWSTR CharFunction::CharToLPWSTR(char charVariable[])
{
    const int BUFFER_SIZE = 2048;
    LPWSTR returnVariable = new WCHAR[BUFFER_SIZE];
    // could assign it to and return a unique_ptr
    MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, BUFFER_SIZE);
    return returnVariable;
}

最好的办法可能是修改函数签名并允许调用者分配一个堆栈缓冲区(类似于输入参数的徒劳)。您也可以保留 return 类型以便于使用。

LPWSTR CharFunction::CharToLPWSTR(char charVariable[], wchar_t returnVariable[])
{
    const int BUFFER_SIZE = 2048;
    MultiByteToWideChar(CP_UTF8, 0, charVariable, -1, returnVariable, BUFFER_SIZE);
    return returnVariable;
}

并在调用代码中;

LPWSTR g_szSystemIni;
char drive[_MAX_DRIVE];
wchar_t buffer[2048];
// ...
lstrcpy(g_szSystemIni, charfunction.CharToLPWSTR(drive, buffer));