2016-12-21 144 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

相關問題