简体   繁体   中英

bug on RELEASE but not on DEBUG

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

Why at least 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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