5

Visual Studio 2003 で次のような問題が発生しています。

void foo(const char*& str, ...) {
    va_list args;
    va_start(args, str);

    const char* foo;
    while((foo = va_arg(args, const char*)) != NULL) {
        printf("%s\n", foo);
    }
}

私がそれを呼び出すとき:

const char* one = "one";
foo(one, "two", "three", NULL);

私は得る:

アクセス違反読み取り箇所 0xcccccccc

printf()行で -- va_arg()0xcccccccc を返しました。私は最終的に、最初のパラメーターがそれを壊す参照であることを発見しました-それを通常の char* にすると、すべて問題ありません。タイプが何であるかは問題ではないようです。参照であると、実行時に失敗します。これは VS2003 の既知の問題ですか、それとも合法的な動作である何らかの方法がありますか? GCC では発生しません。動作がなくなるかどうかを確認するために、新しい Visual Studio でテストしていません

4

1 に答える 1

2

VS2005もクラッシュします。

問題は、va_startが与えられた引数のアドレスを使用し、strが参照であるため、そのアドレスは、スタック上のアドレスではなく、呼び出し元で定義された「1つの」変数のアドレスであるということです。

スタック変数のアドレス(渡される「1」のアドレスを実際に含む引数)を取得する方法はわかりませんが、いくつかの回避策があります。

  • 「constchar*&str」の代わりに、「const char*str」または「constchar**str」を使用してください
  • 次の引数も「固定」引数リストに追加します

このコードは、2番目の選択肢を示しています。

void foo(const char* &str, const char *arg1, ...) {
    if (arg1) {
       va_list args;
       va_start(args, arg1);
       printf ("%s\n", arg1);
       const char* foo;
       while((foo = va_arg(args, const char*)) != NULL) {
           printf("%s\n", foo);
       }
    }
}
于 2010-05-18T08:31:14.863 に答える