开发者

bug on RELEASE but not on DEBUG

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

Why at leas开发者_如何学Got under MSVC 2010 this line of code doesn't bug in DEBUG, but bug in RELEASE ?


The %s format specifier expects a NULL terminated char*. You are passing in a std::string instance. If it works in DEBUG, that's just pure luck.

You should use:

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

This will extract a char* and ensure that the buffer is NULL terminated.

It is possible that in the runtime library std::string has different implementations for DEBUG and RELEASE. Try compiling using both settings, but adding debug symbols to the RELEASE build and then step through the code. Look at the memory location where s is stored. Is there any difference?


Variadic functions like sprintf() are not strictly type safe, in that any argument type is accepted (at compile time) as part of the variadic argument set.

As the other answers have shown, "%s" is a format specifier that expects a NULL terminated character string. Passing a std::string in this case, is likely undefined.

If it works in DEBUG mode, it is likely just "lucky" in that the implementation happens to print the correct result (likely stemming from a c-style cast of the std::string object to a character pointer).


That shouldn't work. Its likely that you are hitting undefined behavior.

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

You should actually probably be using streams instead.


That is wrong. You should be writing this:

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

An object of type std::string cannot be passed to sprintf as there is no format specifier corresponds to std::string. Also, %s expects object of type char* or char[], and c_str() function returns char*, so the above would work.


If you are going to mix up c and c++ then (for performance reasons, based on the comment you gave) then its a good idea to wrap the functions in c++ to avoid these subtle bugs.

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

Be careful once and let the compiler be careful thereafter.

I sometimes think bugs like this are too easy in c and c++, but we can muddle through.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜