gpt4 book ai didi

c++ - wcsncpy_s 函数会导致缓冲区溢出吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:19:30 29 4
gpt4 key购买 nike

我正在尝试了解 wcsncpy_s 函数的工作原理以及它如何防止缓冲区溢出。首先,根据 MSDN,此函数的参数含义如下:

strDest= 目标字符串。

numberOfElements= 目标字符串的大小。

strSource= 源字符串。

count= 要复制的字符数,或 _TRUNCATE。

现在考虑这段代码:

wchar_t a[5];
wcsncpy_s(a, 10, L"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 9);

printf("%d\r\n", sizeof(a));//10
printf("%d\r\n", wcslen(a));//9
wprintf(L"%s", a);//ABCDEFGHI

如果我理解这一切,“a”应该最多包含 4 个宽字符加上一个空终止符,现在包含 9 个宽字符。

现在,由于调试断言失败(VS 2005 编译器),以下代码将导致我的应用程序突然终止:

wchar_t a[5];
wcsncpy_s(a, 10, L"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10);

printf("%d\r\n", sizeof(a));
printf("%d\r\n", wcslen(a));
wprintf(L"%s", a);

有人可以解释上面的代码以及 wcsncpy_s 应该如何防止缓冲区溢出吗?

最佳答案

wcsncpy_s(a, 10, L"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 9);

你在欺骗函数。你告诉它“a 有足够的空间来存储 10 个字符”,而实际上它只有足够的空间来存储 5 个字符。该功能相信您正在向它提供有效信息(它怎么知道您不是?)

请注意,虽然第二个代码片段出现运行时错误,但第一个代码片段同样错误。两者都写到数组末尾 a .

就是说:您使用了错误的 wcsncpy_s 重载: 编译C++代码时,多了一个wcsncpy_s重载是一个模板,用于推导目标数组的大小。如果您要将调用更改为:

wcsncpy_s(a, L"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 9);

模板会推断数组有五个元素并自动将其用作大小。这仅在目标是数组时有效;如果目标是指向数组中初始元素的指针,则它不起作用。

理想情况下,如果您使用 C++,最好完全避免 C 字符串操作:使用 std::wstring或其他一些字符串类型。如果你确实想使用这些与 C 字符串一起工作的函数,至少使用 std::vector<wchar_t>std::array<wchar_t, N>而不是原始数组:搞砸代码要困难得多。例如,

std::array<wchar_t, 5> a;
wcsncpy_s(a.data(), a.size(), L"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 9);

std::vector<wchar_t> 的代码将是相同的。请注意,获取指向底层数组的指针和获取该数组的大小遵循相同的形式,因此编写代码很容易,也很容易检查代码是否正确(只需要对调用进行简单的视觉检查).

关于c++ - wcsncpy_s 函数会导致缓冲区溢出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12644478/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com