C语言va_args实践异常:输出尾随随机值的问题求助
va_args 输出尾随随机值的原因及修复
问题出在参数数量不匹配
你调用print_numbers(4,'s',12,13,14)时,第一个参数num告诉函数要读取4个后续的int参数,但实际上你只传了3个数字(12、13、14)。函数里的循环会严格按照num的值执行4次va_arg读取:
for (int i = 0; i < num; i++) { int val = va_arg(args, int ); printf("%d", val); }
前3次读取到的是你传入的12、13、14,第4次va_arg只能去栈上读取未初始化的随机内存数据,这就是每次运行输出尾随和值都不一样的原因。
顺带提一句:char firstchar = va_arg(args, int);这段是没问题的——C语言可变参数会自动把char、short这类小类型提升为int,所以用int类型读取字符参数是符合规则的。
两种修复方式
方式一:修正调用时的参数数量
把main里的调用改成下面这样,让num的值和实际传入的数字参数数量一致:
print_numbers(3,'s',12,13,14);
这样循环执行3次,刚好读完所有传入的数字,不会越界读取随机内存。
方式二:调整函数的循环逻辑
如果你希望num代表所有可变参数的总数(包括开头的字符),那需要把循环次数改成num-1(因为已经先读取了1个字符参数):
void print_numbers(int num, ...) { va_list args; va_start(args, num); char firstchar = va_arg(args, int); printf("%c", firstchar); // 减去已读取的1个字符参数 for (int i = 0; i < num - 1; i++) { int val = va_arg(args, int ); printf("%d", val); } va_end(args); printf("\n"); }
这时调用时num设为4(1个字符+3个数字,共4个可变参数),也能得到正确输出。
修复后效果
修改完成后,重新编译运行gcc vargs.c -o vargs,程序会输出预期的s121314,不会再出现随机尾随值。
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

