【问题标题】:False sense of security with `snprintf_s``snprintf_s` 带来虚假的安全感
【发布时间】:2010-04-29 14:46:17
【问题描述】:

MSVC 的“安全”sprintf 函数有一个“知道”目标缓冲区大小的模板版本。但是,这段代码在bytes 结束后在堆栈上愉快地绘制了 567890...

char bytes[5];
_snprintf_s( bytes, _TRUNCATE, "%s", "1234567890" );

知道我做错了什么,或者这是一个已知的错误吗?

(我在 VS2005 中工作 - 2008 年或 2010 年没有测试)

【问题讨论】:

  • 哎哟!真是尴尬。

标签: c++ visual-c++ visual-studio-2005 visual-c++-2005


【解决方案1】:

确实是a bug in Visual C++ 2005(我无法访问该链接;Google also has it cached)。

我能够在 Visual C++ 2005 中重现该问题。在 Visual C++ 2008 和 2010 中,字符串被正确截断(bytes 包含 1234\0)并且 -1 按预期返回。

【讨论】:

  • 谢谢!似乎错误报告真的从 MS Connect 网站上消失了......
【解决方案2】:

这个例子确实是正确的。截至版本--

Microsoft Visual Studio 2005
Version 8.0.50727.867 (vsvista.050727-8600)
...
Visual C++ 77626-009-0000007-41722

-- 其中包括 SP1、vista 修补程序和一些库修补程序 -- 上述功能

template <size_t size>
int _snprintf_s(
   char (&buffer)[size],
   size_t count,
   const char *format [,
      argument] ... 
);

仍然有问题。然而,真正令人着迷的是只有 4 个变体函数中的这个函数

  • 好的:int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, :::
  • 越野车:template &lt;size_t size&gt; int _snprintf_s(char (&amp;buffer)[size], size_t count, :::
  • OK:int _snwprintf_s(宽字符版)
  • OK:template &lt;size_t size&gt; int _snwprintf_s(是的,宽字符版OK)

有问题,也就是说,如果一个人使用非模板版本就可以了,如果一个人使用任何一个宽字符版本也可以。太棒了。

【讨论】:

    【解决方案3】:

    示例错误。

    代码应该是:

    char bytes[5];
    _snprintf_s( bytes, 5, _TRUNCATE, "%s", "1234567890" );
    

    对于错误的代码,可能是编译器没有给出任何警告的错误,但可能是对 snprintf 的弱检查。

    【讨论】:

    • -1:这个问题既古老又回答,是关于_snprintf_s 的过载,它需要char 的数组来写入。它不必取大小,因为它可以从模板参数中获取大小。除了在 VC 2005 中,这被打破了。
    猜你喜欢
    • 2011-07-21
    • 2021-12-18
    • 1970-01-01
    • 2013-04-08
    • 2010-12-30
    • 1970-01-01
    • 2019-04-29
    • 2013-08-04
    • 2018-09-09
    相关资源
    最近更新 更多