我在 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);
我得到:
Access violation reading location 0xcccccccc
在 printf()
行上——va_arg()
返回了 0xcccccccc。我终于发现它是打破它的第一个参数是一个引用——如果我把它变成一个普通的 char* 一切都很好。类型是什么似乎并不重要。作为引用会导致它在运行时失败。这是 VS2003 的已知问题,还是有某种合法行为的方式?它不会发生在 GCC 中;我还没有使用较新的 Visual Studio 进行测试以查看该行为是否消失
最佳答案
VS2005 也崩溃了。
问题是 va_start 使用给它的参数的地址,因为 str 是一个引用,它的地址是调用者定义的“一个”变量的地址,而不是堆栈上的地址。
我看不到获取堆栈变量地址的方法(实际上包含正在传递的“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);
}
}
}
关于c++ - 将引用作为命名参数传递给可变参数函数时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2853100/