Passing va_list to vsprintf

Started by
3 comments, last by Zahlman 15 years, 9 months ago
After a bit of googling I still can't figure out this one. This code causes a bus error (or segmentation fault on non-mac).

void ErrorLogger::WriteError(std::string p_ErrorFormat, int p_BufferSize, ...)
{

    // format the string
    va_list args;
    char buf[p_BufferSize];
    va_start(args, p_BufferSize);
    std::vsprintf(buf, p_ErrorFormat.c_str(), args);
    va_end(args);

    // print to console
    printf(buf);

    // write to file and push output
    *m_ErrorFile << buf;
    m_ErrorFile->flush();

}

Advertisement
The code works for me and I don't see anything wrong with it.
Note however that using a non-const value for a fixed size array is non-standard afaik.
char buf[p_BufferSize];

My testcase
#include <cstdio>#include <cstdarg>#include <string>void WriteError(std::string p_ErrorFormat, int p_BufferSize, ...){    // format the string    va_list args;    char buf[p_BufferSize];    va_start(args, p_BufferSize);    std::vsprintf(buf, p_ErrorFormat.c_str(), args);    va_end(args);    // print to console    printf(buf);    // write to file and push output    //*m_ErrorFile &lt;&lt; buf;   // m_ErrorFile-&gt;flush();}int main(){    WriteError("test %s", 256, "works");}


That mix of C and C++ looks rather funky! [smile]

I would not pass the size of the buffer as an argument but simply hard code the size of the buffer. That would change your code to this:

// format the string
char buf[0x400];
memset(buf,0,0x400);

va_list args;
va_start(args, p_ErrorFormat);
std::vsprintf(buf, p_ErrorFormat.c_str(), args);
va_end(args);
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Much Thank! The only motive I had for passing the length of the buffer as an arguement to the function was to insure the buffer had room for the user's error string. Is there any way to do this safe from segmentation faults?
Quote:Original post by Craig_jb
Much Thank! The only motive I had for passing the length of the buffer as an arguement to the function was to insure the buffer had room for the user's error string. Is there any way to do this safe from segmentation faults?


You could have the user pass in the actual buffer. Or you could do it safe from segmentation faults and type errors, and use standard C++ idioms.

template <typename T>ErrorLogger& ErrorLogger::operator<<(const T& t) {  std::cerr << t;  (*m_ErrorFile) << t << std::flush;  return *this;}

This topic is closed to new replies.

Advertisement