Advertisement

the use of va_list

Started by June 20, 2004 09:32 AM
1 comment, last by hplus0603 20 years, 5 months ago
Heyas. Like many others, the Nehe-tutorials use va_list like the following (taken from lesson, hmm, whatever :) )

GLvoid glPrint(const char *fmt, ...) 
{
   char	text[256];
   va_list ap;
   if (fmt == NULL)
      return;   
   va_start(ap, fmt);
   vsprintf(text, fmt, ap);
   va_end(ap);	

   [...]
}
This is a bad way of using a va_list, because as soon as the output string is bigger than 256 chars, we run into a buffer overflow. Fortunatly there is an easy way to precalculate the size of the output-sting, _vscprintf(). This can be used like so:

GLvoid glPrint(const char *fmt, ...) 
{
   char* text;
   va_list ap;
   if (fmt == NULL)
      return;   
   va_start(ap, fmt);
   int len = _vscprintf( fmt, ap) + 1;
   text = new char[len];
   vsprintf(text, fmt, ap);
   va_end(ap);	

   [...]

   delete[] text;
}
No more buffer overflow cause text is always as big as needed. It is important to add "+ 1" to the len, because _vscprintf does not count the terminating 0-character. Of course you should not forget to delete text after using it :) I hope this is found helpfull. schue
Perhaps you could send this in to the newsletter for the tip of the week.
Minister of Propaganda : leighstringer.com : Nobody likes the man who brings bad news - Sophocles (496 BC - 406 BC), Antigone
Advertisement
Dynamic allocation may slow things down (shared locks, touches lots of disparate memory pages, etc).

If your string formatting is performance sensitive (say, for frequent logging) you're probably better off using vsnprintf() and friends instead, which guarantees not to overwrite the buffer; they stop at the end.

Windows has _vsnprintf() which also doesn't overflow, but which isn't guaranteed to zero-terminate the buffer, so you have to do that yourself.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement