Had a customer whose application was crashing after migration from Visual Studio 2005 to Visual Studio 2008. He had the crash dumps as well. The crash call stack had some CRT string format functions like vsprintf. This gave to us a fair inkling that parameters passed in are wrong.
Customer had a format string, something like this: “My string format [%s]”.
At the point of crash the output buffer looked like this: “My string format[“. It became quite evident that the crash is happening when the %s in the format string was being replaced by the actual string. Quite evident that something’s wrong with the parameter passed in for replacing the %s format specifier.
Checking code saw something like this…
MyString mystr = “MS rocks”;
MyFormatters::Format(“My string format [%s]”, mystr);
You should never do this. %s is expecting a “raw string” and do not pass in anything else. This is wrong even if your class has a raw string as its first member, imagine if you have a virtual function in the class or if someone decides in the future this class should be derived further.
Always pass in a raw string pointer and nothing else to the string format functions for expanding the format specifier: %s. The string format family of functions doesn’t check the type passed in. Those functions work on varargs hence compiler doesn’t help as well.
In this case we fixed above code likewise:
MyFormatters::Format(“My string format [%s]”, mystr.c_str());
You might have an obvious question as to why it worked in Visual Studio 2005, the answer is pretty obvious as well. I’ll leave that for you to answer.