如何在调试版本中阻止strncpy_s填充目标缓冲区?

时间:2014-09-24 12:23:46

标签: c++ string visual-c++

我维护了一大段仍然使用strncpy的遗留代码。我现在已开始将strncpy的使用替换为其安全对应strncpy_s。我注意到strncpy_s用-2值填充目标缓冲区 - 但仅在调试版本中!在发布版本中,不会发生填充。

例如:

char buffer[3];
// buffer becomes 00000000  00000000  00000000
memset(buffer, 0, sizeof(buffer));
// buffer becomes 01100001  00000000  11111110
//                97 ('a')  0        -2
strncpy_s(buffer, sizeof(buffer), "a", _TRUNCATE);
// i is -2
int i = buffer[2];

MSDN docs没有提到这种填充行为,在我的情况下,它确实是我不想要的东西,因为我的遗留代码依赖于缓冲区的归零部分仍然存在的事实字符串复制时归零并且不会被覆盖。

有没有办法阻止strncpy_s在调试版本中填充目标字符串?

请注意,我已使用Visual Studio 2010和Visual Studio 2013对此进行了测试。

2 个答案:

答案 0 :(得分:7)

strncpy_s的定义是null终止符之外的元素采用未指定的值。 strncpy的定义是这些元素设置为0。如果您不想要此行为,请不要使用strncpy_s

此外,strncpy_s在输入对缓冲区来说太大的情况下与strncpy的行为不同。

strncpystrncpy_s的有效用例很少。使用strcpysnprintfmemcpy几乎总是更好。我倾向于使用这三个函数中最适合该任务的那个函数。

将它称为“安全对应物”相当夸张,IMO。如果你传递正确的参数,“非安全”版本实际上都是完全安全的;如果你没有传递正确的论据,那么这两种变种都不安全。

如果您使用strncpy的代码实际上没有被窃听,并且您依赖于零填充功能,则没有理由对其进行更改。

答案 1 :(得分:5)

strcpy_s()将仅在调试模式下使用'FE'填充缓冲区。

您可以通过调用_CrtSetDebugFillThreshold(0)

明确关闭此功能