将引用作为命名参数传递给可变参数函数时出现问题

时间:2010-05-17 21:48:44

标签: c++ visual-studio reference visual-studio-2003 variadic-functions

我在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的已知问题,还是某种方式存在合法行为?它不会发生在海湾合作委员会;我没有使用较新的Visual Studios进行测试,看看行为是否消失

1 个答案:

答案 0 :(得分:2)

VS2005也崩溃了。

问题是va_start使用给它的参数的地址,并且由于str是引用,它的地址是调用者中定义的“one”变量的地址,而不是堆栈上的地址。

我认为无法获取stack-variable的地址(实际包含正在传递的“one”地址的参数),但是有一些解决方法:

  • 使用“const char * str”或“const char ** str”
  • 而不是“const char *& str”
  • 还将下一个参数添加到“固定”参数列表

此代码说明了第二种选择:

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