2012-03-01 2 views
1

Я получаю ошибку нарушения прав доступа (используя Microsoft Visual C++ 2005) при передаче параметра va_list из одной функции-члена в другую по значению. Если я передам его по ссылке, все работает так, как ожидалось, но va_list не должен передаваться по ссылке, не так ли?Нарушение прав доступа при передаче va_list по значению

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; 
} 

ответ

1

Если вы выполняете выполнение, обе функции вызываются в ожидаемом порядке?

Обе указанные функции имеют схожие сигнатуры, поэтому первая проверка - убедиться, что вызов происходит должным образом. Это особенно важно, так как va_list типично типизирован до char *, поэтому getformatted("foo%s", "bar") можно было бы назвать без вызова getformatted(const char *, ...).

Если это так, и vsprintf использует va_next в любой момент, поведение будет неопределенным. Некоторые компиляторы обрабатывают функции va_ как простые макросы, в то время как другие имеют значительные функции.

Обычно для решения этой проблемы функция с va_list будет иметь префикс v (vsprintf и др.), Чтобы устранить любую потенциальную двусмысленность.

В лучшем случае, поскольку вы используете C++, обычно предпочтительны std::stringstream или boost::format. Оба предоставят вам безопасность типов и предотвратят большинство ситуаций, подобных этому, в то время как последний сохраняет большую часть синтаксиса printf.

2

В <stdarg.h>:

typedef char * va_list 

так A().getformatted("foo%s", "bar") звонит A::getformatted(char const * a_format, va_list /*&*/ a_args) из-струнной буквального убывающим к char * благодаря совместимости C.

Смежные вопросы