2012-04-16 23 views
0

によって設定された長さIが正しく動作するユーティリティCの機能を持っている持っているときは動作しません:vsprintf_s()va_listのは、ローカル変数

void UtilDisplayMessage(char* strCaption, char* strMessageFormat, int iArgCount, ...) 
{ 
    // Initialize the variable arg list 
    va_list lstArgs; 
    va_start(lstArgs, iArgCount); 

    // Format the message 
    vsprintf_s(g_strMessage, UTIL_DEF_MESSAGE_SIZE, strMessageFormat, lstArgs); 

    // Destroy the variable arg list 
    va_end(lstArgs); 

    // Use formatted string here... 
} 

をしかし、私は「iArgCount」パラメータを削除したいと思いますので、私はしましたこのようになりますテスト関数を作った:

void UtilDisplayMessageEasy(char* strCaption, char* strMessageFormat, ...) 
{ 
    // Initialize the variable arg list 
    va_list lstArgs; 

    int iParamCount = 1; 
    va_start(lstArgs, iParamCount); 

    // Format the message 
    vsprintf_s(g_strMessage, UTIL_DEF_MESSAGE_SIZE, strMessageFormat, lstArgs); 

    // Destroy the variable arg list 
    va_end(lstArgs); 

    // Use formatted string here... 
} 

しかし、私はこの呼び出しで整数値を渡す場合、私は偽の結果を得る:

UtilDisplayMessageEasy("TEST", "The value is %i.", 1); 
私はこの呼び出しで文字列を渡すとき

と私はアクセス違反の例外を取得:

UtilDisplayMessage("TEST", "This is only a %s.", 1, "TEST"); 

本当にあります:私はそうのように私の元の関数を呼び出す場合それでも

UtilDisplayMessageEasy("TEST", "This is only a %s.", "TEST"); 

、それが正常に動作しますva_start()に引数パラメータまたはローカルパラメータを渡すかどうかの基本的な違いはありますか?

また、可変パラメータはあまり安全ではなく、気をつけて使用する必要がありますが、この無害なものがアラームを鳴らすものではないはずです。

この問題に関してご意見をお寄せいただきありがとうございます。

+0

'UtilDisplayMessageEasy'では' va_start(lstArgs、iParamCount);を 'va_start(lstArgs、strMessageFormat);に変更します。 –

+0

ああ!それでおしまい!どうもありがとうございました! – BlazeCell

答えて

1

va_startの2番目の引数は、関数宣言の...より前の最後のパラメータである必要があります。したがって、最初のケースではiArgCount、後のケースではstrMessageFormatである必要があります。 2番目の引数(ローカル変数など)に何か他のものを使用すると、未定義の動作が得られます。コンパイラによってエラーが発生する可能性がありますが、それを静かに受け入れてランダムな処理を行うだけです。

+0

うわー!あなたは私がドキュメントでそれを見たと思います。どうもありがとうございます! – BlazeCell

0

変数va_listは、その直前の引数から...の開始アドレスを導出するために使用されます。それは要件です。ローカルを使用することはできません 、あなたの代わりに

va_start(lstArgs, strMessageFormat); 

をしたいかもしれません。

+0

ありがとうございました! – BlazeCell

関連する問題