2012-03-01 58 views
1

當通過值將va_list參數從一個成員函數傳遞到另一個成員函數時,出現訪問衝突錯誤(使用Microsoft Visual C++ 2005)。如果我通過引用傳遞所有內容,但是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(const char *, ...),就可以很好地調用getformatted("foo%s", "bar")

如果是這種情況,並且vsprintf在任何時候都使用va_next,則行爲將是未定義的。一些編譯器將va_函數當作簡單的宏來處理,而其他函數則具有重要的功能。

通常爲了解決這個問題,帶有va_list的函數將以v(等)作爲前綴以消除任何可能的不明確性。

在最好的情況下,由於您使用的是C++,通常最好使用std::stringstreamboost::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兼容性。