Reputation: 1567
I'm not sure why I'm seeing an EXC_BAD_ACCESS in the following code:
template <typename ArgType>
String Format(ArgType args, ...) const {
va_list argList;
va_start(argList, args);
// determine num of chars needed, don't store anything anywhere though!
size_t charsNeeded = vsnprintf(NULL, 0, ToStdString().c_str(), argList);
va_end(argList);
// print formatted string into buf
va_start(argList, args); // EDIT: new va_list here
char buf[charsNeeded];
vsprintf(buf, ToStdString().c_str(), argList);
va_end(argList);
return String(buf);
}
EDIT: I should probably mention that the code is supposed to be used like this:
String str = String("Hello, %s!").Format("World");
I should mention String is a small wrapper class which has a ToStdString() method which returns a std::string member var.
It's segfaulting on the vsnprintf() call, but I have no idea why!
Upvotes: 2
Views: 1319
Reputation: 73
va_start
initialises the va_list
to get arguments after the one specified, since in your example you are only sending one argument to the method, the va_list
is empty.
You also need to reinitialise the va_list
after calling vsnprintf
.
You need to rethink the signature of your method, could do a static function:
class String : public std::string {
public:
String(std::string str) : std::string(str) {}
String(char *str) : std::string(str) {}
static String Format(String format, ...) {
va_list argList;
va_start(argList, format);
// determine num of chars needed, don't store anything anywhere though!
size_t charsNeeded = vsnprintf(NULL, 0, format.c_str(), argList);
va_end(argList);
va_start(argList, format);
// print formatted string into buf
char buf[charsNeeded];
vsprintf(buf, format.c_str(), argList);
va_end(argList);
return String(buf);
}
};
EDIT:
If you are looking to format strings the best solutions is probably to use a std::stringstream
: http://www.cplusplus.com/reference/sstream/stringstream/stringstream/
Upvotes: 4