【问题标题】:sprintf_s caused for crashsprintf_s 导致崩溃
【发布时间】:2011-08-07 11:28:30
【问题描述】:

我遇到了问题。 示例:

try
{
    char strMes[6];
    sprintf_s(strMes, sizeof(strMes), "%s", "012345678");
    printf(strMes);
}
catch(...)
{
    printf("Wrong\n");
}

在调试环境中导致调试器“缓冲区太小”消息。

在发布环境中导致崩溃。

我尝试将 try-catch 块替换为 __try-__except(EXCEPTION_EXECUTE_HANDLER) 块,但我得到了相同的行为。

我对 sprintf_s 函数有大约 1K 次调用,因此将 sprintf_s 替换为 _snprintf_s 不是我的选择。 (见sprintf_s with a buffer too small

请帮忙!

【问题讨论】:

  • 您期待什么?您正在尝试写入缓冲区的末尾,或者将写入限制为缓冲区的大小(在您的情况下,您可以在一个体面的编辑器中通过简单的搜索/替换来完成)或扩大缓冲区。
  • 使缓冲区更大/将sprintf_s 替换为采用相同参数的_snprintf

标签: c++ error-handling printf


【解决方案1】:

首先,我认为您应该使用snprintf 而不是sprintf_s

其次,有一个 invalid paramater handler 用于 CRT 被调用。尝试设置。

【讨论】:

    【解决方案2】:

    必须在进一步使用strMes 之前检查sprintf_s 的返回值。否则你怎么知道缓冲区是否足够大? sprinft_s 可能没有任何内容写入strMes,因此它仍未初始化。这就是导致崩溃的原因(尝试删除sprintf_s,它也可能会崩溃。)

    来自sprintf_s 文档:

    写入的字符数,如果发生错误,则为 –1。如果 buffer 或 format 为空指针,sprintf_s 和 swprintf_s 返回 -1 并将 errno 设置为 EINVAL。

    PS:由于 try/catch,您应该标记这个问题 C++ 而不是 C。

    【讨论】:

      【解决方案3】:

      阅读documentation

      .... 如果任一检查失败,则调用无效参数处理程序,如 参数验证中描述...

      默认行为是投掷。你可以override它。

      【讨论】:

        【解决方案4】:

        如果你的 VS 版本支持,你应该在上面运行代码分析。

        了解About Code Analysis

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-23
          • 2020-12-02
          • 2013-11-11
          • 2011-01-24
          • 2015-02-23
          • 2011-04-23
          • 1970-01-01
          相关资源
          最近更新 更多