wcscpy_s后读取字符串字符时出错
Error reading characters of string after wcscpy_s
我对wcscpy_s
函数有问题。wcscpy_s
返回后,我的函数的参数(stringOne
和stringTwo
)是不可读的。这是显示问题的简单演示。
void testFunc(LPCWSTR stringOne, LPCWSTR stringTwo) {
wchar_t* defaultVal = L"Default";
wchar_t tmp[100];
int lenBefore = wcslen(stringOne); // Works
auto result = wcscpy_s(tmp, sizeof(tmp), defaultVal);
int len = wcslen(tmp);
int len2 = wcslen(stringOne); // Throws Exception Access violation
}
int main() {
testFunc(L"Test", L"Test");
}
wcscpy_s
的文档指出,此函数的调试版本使用特殊值 0xFE
填充目标缓冲区。
调用wcscpy_s(tmp, sizeof(tmp), defaultVal);
时,传递tmp
缓冲区的大小,但wcscpy_s
需要字符数的长度。因此,您传递给wcscpy_s
的长度是应有的长度的两倍,并且当tmp
缓冲区被0xfe
覆盖时,即使源字符串(L"Default";
)的长度很小,您也会得到缓冲区溢出和未定义的行为。
所以使用 _countof(tmp)
而不是 _sizeof(tmp)
.
也就是说,我建议你学习如何使用Visual Studio调试器。
正如 Michael Walz 的回答中已经解释的那样,由于传递不正确的缓冲区大小而导致缓冲区溢出。
除了他建议使用 _countof(tmp)
而不是 sizeof(tmp)
之外,我还想补充一点,C++ 中有一个方便的 wcscpy_s() 重载,可以自动推断出正确的缓冲区大小:
template <size_t size> errno_t wcscpy_s( wchar_t (&strDestination)[size], const wchar_t *strSource ); // C++ only
基本上,你可以像这样编写更简单的代码,这将起作用:
wchar_t tmp[100];
// Use the C++-only template overload of wcscpy_s
// that automatically deduces the destination buffer size
auto result = wcscpy_s(tmp, defaultVal);
如果您使用此重载,则可以免受那些sizeof
/_countof
不匹配类型的错误的影响。
请注意,这种C++重载仅在您拥有像wchar_t tmp[100]
这样的静态缓冲区时才有效,因为C++编译器必须能够在编译时计算出缓冲区大小。另一方面,当指针指向动态分配的缓冲区时,必须显式传递正确的缓冲区大小。
相关文章:
- 分段 使用 MPI_Gather 收集字符数组时出错
- 将常量字符* 转换为字符时出错
- 读取字符串C++的字符时出错
- 为什么常量字符*到常量字符转换出错?
- 读取字符串字符时出错 - 对于数组中的字符串值
- 通过字符串::插入插入字符时出错
- 读取字符串字符时出错
- 计算字符串中字符的出现次数时出错
- C++ 使用 Strtok 读取字符串字符时出错
- C++:使用 fgets() 读取字符输入时出错
- C ++ ifstream 无法读取字符串,并且在读取字符时出错
- 尝试将常量字符 [] static_cast<>为无符号字符 * 时出错
- 从字符串中读取字符时出错
- 英特尔 TBB,parallel_pipeline,当我在阶段之间传递常量字符*时出错
- 转换(常量字符*)变量出错
- 为什么我从字符转换为字符时出错
- 读取字符串C++的字符时出错
- wcscpy_s后读取字符串字符时出错
- 读取字符串 的字符时出错.分配内存
- C++字符出错