【问题标题】:bug on RELEASE but not on DEBUGRELEASE 上的错误,但 DEBUG 上没有
【发布时间】:2011-07-25 18:00:46
【问题描述】:
std::string s("foo");
sprintf(buf,"%s",s);

为什么至少在 MSVC 2010 下,这行代码在 DEBUG 中没有错误,但在 RELEASE 中没有错误?

【问题讨论】:

  • 你为什么要开始这样做?
  • 谁给我-1没有任何解释??我相信理解为什么像这样的典型错误可以绕过调试模式是很有趣的
  • 他真的应该改用字符串流或者完全改用C!
  • 是的,但它是用于实时处理的......而且 sprintf 比 c++ 流更快!
  • @Guillaume07:我没有将其列为 -1。但是,为 Debug 目标编译 C++ 并不能保证它会为您找到所有错误。事实上,Debug 根本不会为您找到任何错误。相反 - 除非您更改了设置 - 它通常会切换优化并添加调试符号的创建,以便您可以设置断点并逐步执行代码(简单地说)。不过,我可能误解了你。

标签: c++ visual-studio-2010


【解决方案1】:

%s 格式说明符需要以 NULL 结尾的 char*。您正在传递一个 std::string 实例。如果它在 DEBUG 中工作,那只是运气。

你应该使用:

std::string s("foo");
sprintf(buf, "%s", s.c_str());

这将提取char* 并确保缓冲区以NULL 终止。

可能在运行时库中std::string 对 DEBUG 和 RELEASE 有不同的实现。尝试使用这两种设置进行编译,但将调试符号添加到 RELEASE 构建,然后逐步执行代码。查看存储s 的内存位置。有什么区别吗?

【讨论】:

  • 也许吧,但我相信计算机科学没有运气 ;)
  • 幸运的是,您很幸运(?)std::string 的调试版本被设计为包含指向对象内存中第一个偏移量处的字符串数据的指针。在这种情况下,我认为库作者可以通过在 DEBUG 构建中对象的第一个内存偏移量处添加其他内容来提供帮助。
【解决方案2】:

sprintf() 这样的可变参数函数不是严格类型安全的,因为任何参数类型都被接受(在编译时)作为可变参数集的一部分。

正如其他答案所示,"%s" 是一个格式说明符,它需要一个以NULL 结尾的字符串。在这种情况下传递 std::string 可能是未定义的。

如果它在 DEBUG 模式下工作,很可能只是“幸运”,因为实现恰好打印了正确的结果(可能源于 std::string 对象到字符指针的 c 样式转换)。

【讨论】:

    【解决方案3】:

    这应该行不通。您可能遇到了未定义的行为。

    std::string s("foo");
    sprintf(buf,"%s",s.c_str());
    

    您实际上应该使用流来代替。

    【讨论】:

      【解决方案4】:

      这是错误的。你应该这样写:

      std::string s("foo");
      sprintf(buf,"%s",s.c_str());
      

      std::string 类型的对象不能传递给sprintf,因为没有对应于std::string 的格式说明符。此外,%s 需要char*char[] 类型的对象,而c_str() 函数返回char*,因此上述方法可以工作。

      【讨论】:

        【解决方案5】:

        如果您打算混合使用 c 和 c++(出于性能原因,基于您提供的评论),那么最好将函数包装在 c++ 中以避免这些细微的错误。

        struct console_out
        {
          static void 
          print(const string& s)
          {
            sprintf(buf, "%s", s.c_str());
          }
          //other overloads should you want them
        }
        

        小心一次,之后让编译器小心。

        我有时认为这样的错误在 c 和 c++ 中太容易了,但我们可以应付过去。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-28
          • 1970-01-01
          • 1970-01-01
          • 2023-03-25
          • 1970-01-01
          • 2011-03-16
          相关资源
          最近更新 更多