2016-12-21 112 views
0

我正在看C的一个可变参数的this example,写成GNU.org。我的操作系统是Debian 8.6。为什么这个GNU C variadic函数返回一个巨大的数字?

这里是我的就可以了轻微的变化,文件名是ex.c

#include <stdarg.h> 
#include <stdio.h> 

int addEmUp(int count,...){ 
    va_list ap; // where list of arguments are stored 
    int i, sum; 

    va_start(ap,count); // initialize the argument list 

    sum= 0; 
    for(i=0; i<count; i++) 
     sum += va_arg(ap,int); // get the next argument value 

    va_end(ap); // clean up 

    return sum; 
} 

int main(void){ 
    printf("%d\n", addEmUp(3,4,5,6)); 
    printf("%d\n", addEmUp(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); 
    printf("%d\n", addEmUp(10,10,10,10)); 
    return 0; 
} 

这里是我的makefile _example.mak

CFLAGS=-Wall -g 
CFILE=ex 

run: 
    cc $(CFILE).c -o $(CFILE) $(CFLAGS) 
    ./$(CFILE) 
    rm -f $(CFILE) 

当我打开终端,运行输出make -f _example.mak

./ex 
15 
55 
1141373223 
rm -f ex 

为什么第三个addEmUp() print 1141373223

+1

您传递了无效的长度。应该有10个后续参数,但只有3个。所以它使用垃圾值。 –

回答

4

您有未定义的行为。

您发送10作为第一个参数,但您只需要3个附加参数即可调用addEmUp()

printf("%d\n", addEmUp(3, 10, 10, 10)); 

当你有一个未定义的行为,你可以不知道会发生什么。当你的功能addEmUp()变得太过va_arg()。您可以引起了不少心思:

  • 分段故障
  • 错误的行为(你)

像@ user3553031说,在注释:

最很可能,你加入的其他数字是调用堆栈中的其他数据 - 例如保存的返回地址,甚至可能是当前的val总和本身。这很大程度上取决于您的操作系统,编译器和机器体系结构; C没有定义调用堆栈的结构,甚至不需要它。

+1

最有可能的是,添加到sum中的那些其他数字是调用堆栈中的其他数字 - 例如保存的返回地址,甚至可能是sum的当前值。在某些平台上,您也可能会投入一些注册内容。这很大程度上取决于您的操作系统,编译器和机器体系结构; C没有定义调用堆栈的结构,甚至不需要它。 – user3553031

相关问题