我维护了一大段仍然使用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对此进行了测试。
答案 0 :(得分:7)
strncpy_s
的定义是null终止符之外的元素采用未指定的值。 strncpy
的定义是这些元素设置为0
。如果您不想要此行为,请不要使用strncpy_s
。
此外,strncpy_s
在输入对缓冲区来说太大的情况下与strncpy
的行为不同。
strncpy
或strncpy_s
的有效用例很少。使用strcpy
,snprintf
或memcpy
几乎总是更好。我倾向于使用这三个函数中最适合该任务的那个函数。
如果您使用strncpy
的代码实际上没有被窃听,并且您依赖于零填充功能,则没有理由对其进行更改。
答案 1 :(得分:5)
strcpy_s()
将仅在调试模式下使用'FE'
填充缓冲区。
您可以通过调用_CrtSetDebugFillThreshold(0)
明确关闭此功能