任何参数的C ++函数都会导致Segmentation故障

时间:2016-08-24 11:14:02

标签: c++ parameters segmentation-fault variadic-functions

这是我的程序,有谁知道为什么?

#include <iostream>
#include <string>
#include <stdarg.h>
using namespace std;

void say(char* name ...)
{
    cout << "Hello, ";
    cout << name ;
    va_list ap;
    va_start(ap,name);

    for(;;){
        char* str = va_arg(ap, char*);
        if (str == 0) break;
        cout << ", " << str;
    }
    cout << endl;
    va_end(ap);
}
int main()
{
    char *a = "atom";
    char *b = "johhny";
    char *c = "jim";
    say(a,b,c);
}

当我运行它时,我得到了这个:

Program received signal SIGSEGV, Segmentation fault.
0x0000003f0b06fed0 in strlen () from /lib64/tls/libc.so.6

以下是调试信息:

24      cout << "Hello, ";
(gdb) n
25      cout << name ;
(gdb) n
27      va_start(ap,name);
(gdb) n
30          char* str = va_arg(ap, char*);
(gdb) n
31          if (str == 0) break;
(gdb) n
32          cout << ", " << str;
(gdb) n
29      for(;;){
(gdb) n
30          char* str = va_arg(ap, char*);
(gdb) n
31          if (str == 0) break;
(gdb) n
32          cout << ", " << str;
(gdb) n
29      for(;;){
(gdb) n
30          char* str = va_arg(ap, char*);
(gdb) n
31          if (str == 0) break;
(gdb) n
32          cout << ", " << str;
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x0000003f0b06fed0 in strlen () from /lib64/tls/libc.so.6
(gdb) n
Single stepping until exit from function strlen,
which has no line number information.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

1 个答案:

答案 0 :(得分:4)

调用va_arg次数超过实际参数数量是未定义的行为。您没有任何自动方法来检测输出结束。您必须自己跟踪有效参数的数量。有多种方法可以做到这一点,例如:

  • 您可以将null或任何特殊值传递给signal end。
  • 您可以将参数数量作为单独的强制参数传递。
  • 您可以维护某种格式字符串,例如printfscanf