繁体   English   中英

发布时出现错误,但调试失败

[英]bug on RELEASE but not on DEBUG

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

为什么至少在MSVC 2010下,此行代码不会在DEBUG中出错,而在RELEASE中出错?

%s格式说明符期望以NULL结尾的char* 您正在传递一个std::string实例。 如果它在DEBUG中有效,那就太幸运了。

您应该使用:

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

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

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

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

如其他答案所示, "%s"是一种格式说明符,期望以NULL结尾的字符串。 在这种情况下,传递std :: string可能是不确定的。

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

那不行 很可能是您遇到未定义的行为。

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

实际上,您实际上应该使用流。

那是错的。 您应该这样写:

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

无法将类型为std::string的对象传递给sprintf因为没有格式说明符对应于std::string 此外, %s期望使用char*char[]类型的对象,并且c_str()函数返回char* ,因此上述方法可以正常工作。

如果要混合使用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 ++中太容易了,但是我们可以解决。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM