2013-07-21 61 views
3

我正在學習C,我不知道該如何描述,但爲什麼在下面的代碼中取消註釋行11會打破此程序?爲什麼這項任務會破壞我的計劃?

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    printf("argc: %d\n", argc); 

    char *states[] = {}; 
    int i = 0; 
    while(i < argc) { 
     printf("arg %d: %s\n", i, argv[i]); 
     //states[i] = "test"; 
     i++; 
    } 


    return 0; 
} 

當我取消註釋該行並運行該程序,我得到這樣的:

[email protected]:~/code$ ./myprog aaa bbb ccc 
argc: 4 
arg 0: ./lc 
arg 1: aaa 

爲什麼states[i] = "test";打破while循環?當我註釋它時,我看到所有打印的參數。

+7

好吧,其中一個'州'大小爲零。你應該給它一個尺寸。也許'char * states [argc];',如果你允許VLA。 – Ryan

+1

C不允許長度爲0的數組,也不允許初始值設爲空。也許這些是你的編譯器允許的擴展(不是一個好主意),但很可能你沒有足夠高的警告級別。 –

回答

9

它因爲數組states爲空而中斷。讓它的argc大小(這是允許的C99)來解決這個問題:

char *states[argc]; 

其原因如下:char *states[] = {};使得零個元素的數組,所以任何非關聯states[i]是不確定的行爲。

+0

是的,那正是我想要做的。我忘了你不能用C做這件事。但我仍然對未定義的行爲感到困惑。當程序到達第11行時,程序是否會被轟炸,所以我永遠不會增加? – red888

+1

未定義的行爲就是這樣 - 根據C規範,它可以對程序有任何*任何影響,因爲規範沒有說明會發生什麼。在你的情況下,'i'變量可能被一些隨機指針值覆蓋,導致循環過早停止。 – nneonneo

+0

@ user1028270:你可能正在改變'我'。我可以在64位Linux/gcc上通過在'char * states [] = {};''之前聲明'i'並使之成爲'long'來重現它。 – Ryan

0

您需要爲字符數組分配內存。如果argc是要存儲的字符數:

char *states[argc]; 

有效。或者,如果你要動態地擴展它,你可以使用堆,保留一個計數器變量,並添加以下在循環:

states = (char *) realloc(sizeStates + sizeof(char)); 
sizeStates++; 

爲了騰出空間給下一個字符分配它。

+2

應該是'sizeof(char *)',而不是'sizeOf(char)'。 – Ryan

相關問題