2011-10-25 51 views
2

我今天遇到一個奇怪的問題。我們簡單瞭解一下這個簡單的代碼片段:C99命令行不打印任何東西在這個C編程案例

typedef struct 
{ 
    /* The number of index terms */ 
    int nTerms; 
    /* Information about each index term */ 
    TERMINFO *terms; 
} INDEX; 

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts) 
{ 
    INDEX *ind = NULL; 
    ind->nTerms = 5; 
    return ind; 
} 

int main(int argc, char *argv[]) { 
    ... // declare and assign values for TERMFILE, DIRS and opts. 
    INDEX *ind = buildIndex(TERMFILE, DIRS, sizeof(DIRS), opts); // LINE A 
    printf("Does NOT print %d\n",ind->nTerms); // LINE B 
    printf("Does NOT print as well"); // LINE C 
    return 0; 
} 

當我編譯這個程序,有沒有發生錯誤,但是當我運行編譯的文件,它不會打印出任何東西到條命令行(我在Windows機器上使用PuTTy)。當我刪除線LINE ALINE B時,就會變得奇怪,然後可以打印LINE C。

簡而言之,無論打印出來(或執行?),LINE A都行不通。

我不知道我的代碼是否有問題。

+2

你的第二個'LINE A'是否意味着'LINE B'? – Andrew

+0

哎呀對不起,有人爲我編輯 – antiopengl

回答

4

在你解引用NULL指針第二行,這會導致不確定的行爲:

INDEX *ind = NULL; 
ind->nTerms = 5; 
return ind; 

你需要作出ind指向非本地存儲器,即,從與堆分配malloc它,或者將其設置爲指向與全球壽命的變量:

INDEX *ind = malloc(sizeof(INDEX)); 

if (ind != NULL) 
    ind->nTerms = 5; 

return ind; 

對FR的責任在這種情況下,返回的結構(如果它是NULL,則不解除引用它)被委託給調用者。

請注意,如果您要將ind指向本地聲明的變量並將其返回,則每當調用方嘗試取消引用指針時都會發生UB,因爲在函數終止後會恢復堆棧。

+0

+1在這種情況下最可能發生崩潰的未定義行爲 – jv42

+0

+1未定義的行爲,但_without_堅持崩潰。完成但沒有輸出任何東西是完全可以接受的,因爲UB是機器崩潰自己形成裸奇點。**任何**都可能發生! – paxdiablo

+0

@Blagovest,我做了一些小的調整來處理malloc錯誤,希望你不介意。 – paxdiablo

4

爲什麼它不打印任何東西的原因是因爲它的崩潰:

INDEX *ind = NULL; 
ind->nTerms = 5; 

你取消對NULL。 (這是不確定的行爲)

當您刪除A線和B線,它不會崩潰,因此打印C線(也忘了\n在線c刷新緩衝區。)

什麼你需要通過malloc動態分配ind並返回。 (並確保以後釋放它)

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts) 
{ 
    INDEX *ind = malloc(sizeof(INDEX)); // Allocate 

    // You may wish to check if `ind == NULL` to see if the allocation failed. 

    ind->nTerms = 5; 
    return ind; 
} 

int main(int argc, char *argv[]) { 
    ... // declare and assign values for TERMFILE, DIRS and opts. 
    INDEX *ind = buildIndex(TERMFILE, DIRS, sizeof(DIRS), opts); // LINE A 
    printf("Does NOT print %d\n",ind->nTerms); // LINE B 
    printf("Does NOT print as well"); // LINE C 

    free(ind); // Free 

    return 0; 
} 
+0

+1不錯的答案(: – antiopengl

+0

)請注意,在函數中分配一個對象並將它釋放到程序的另一部分通常是不鼓勵的。您可以在* main *中分配指針,它作爲'buildIndex()'和'free()'的主要參數。 – Gui13

0

您可以調用包含這兩行的函數buildIndex

INDEX * ind = NULL; ind-> nTerms = 5;

因此,您正在解引用空指針。這是錯誤的。你的程序崩潰了,所以不要再跑了。

1

您的問題似乎是在buildIndex

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts) 
{ 
    INDEX *ind = NULL; 
    ind->nTerms = 5; 
    return ind; 
} 

正如你所看到的,你設置indNULL,然後嘗試參考隨即。這是未定義的行爲,所以接下來可能會發生任何事情。