简体   繁体   中英

Access violation when passing a va_list by value

I'm getting an access violation error (using Microsoft Visual C++ 2005) when passing a va_list parameter from one member function to another by value. If I pass it by reference everything works as expected but va_list isn't supposed to be passed by reference, is it?

class A
{
public:
    char * getformatted( char const * a_format, ... )
    {
        va_list argp;
        va_start( argp, a_format );
        char * result = getformatted( a_format, argp );
        va_end( argp );
        return result;
    }
    char * getformatted( char const * a_format, va_list /*&*/ a_args )
    {
        static char buffer[ 256 ];
        int length = vsprintf( buffer, a_format, a_args );  // Access violation.
        return buffer;
    }
};

int main( int argc, char * argv[] )
{
    char * str = A().getformatted( "foo%s", "bar" );
    return 0;
}

In <stdarg.h> :

typedef char * va_list

so A().getformatted( "foo%s", "bar" ) is calling A::getformatted( char const * a_format, va_list /*&*/ a_args) due to a string literal decaying to char * due to C compatibility.

If you step through execution, are both functions being called in the expected order?

Both the functions shown have similar signatures, so the first check is to make sure the call is occurring properly. This is particularly important since va_list is typically a typedef to char * , so getformatted("foo%s", "bar") could very well be called without getformatted(const char *, ...) being called first.

If that is the case, and vsprintf uses va_next at any point, the behavior will be undefined. Some compilers handle the va_ functions as simple macros, while others have significant functions.

Typically to solve this, the function with va_list will be prefixed with a v ( vsprintf et al) to remove any potential ambiguity.

In the best case, since you're using C++, a std::stringstream or boost::format are generally preferable. Both will give you type safety and prevent most situations like this, while the latter retains most of printf 's syntax.

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