2013-02-14 192 views
4

這是作業分配的一部分。C返回字符[]警告「返回本地變量的地址」

我想在我的方法getLine中讀取並返回一行文件。

char *getLine(FILE *input) { 
    char line[30]; 
    if(fgets(line, sizeof(line), input)!=NULL) 
    { 
     return line; 
    }else{ 
     return NULL; 
    } 
} 

這似乎從有關指針我已經教了什麼工作,但是我無法刪除警告消息warning: function returns address of local variable [enabled by default]。此警告指的是線路return line;。我的任務要求編譯時我沒有警告或錯誤。我沒有看到我做錯了什麼。

我發現的大部分幫助爲文本行提供了malloc-ing空間,但是我們還沒有在課堂上介紹過,即使我已經在另一課中做了一些。這真的是最好的方法嗎?如果是這樣,我可以在程序的任何地方釋放嗎?

+1

函數返回時局部變量不再存在,則返回一個懸掛指針。讓我找到一個騙局。 – 2013-02-14 10:21:12

+0

如果要在堆上分配內存,請使用'malloc'。這個問題在這裏已經被無數次地提出。 – KBart 2013-02-14 10:22:29

+0

這是很常見的錯誤,所以你肯定會發現幾十篇有關遇到這個問題的文章:)其中一個原因是,大多數編譯器甚至不會警告你你在做什麼:http:// ideone。 com/S5Se71 – LihO 2013-02-14 10:32:47

回答

12

char line[30];是一個具有自動存儲持續時間的數組。一旦執行超出了函數的範圍,釋放它駐留的內存將被釋放,因此返回的內存指針變爲無效(懸掛指針)。

試圖訪問內存,該內存已被釋放,導致未定義的行爲

您可以動態地分配你的陣列,讓來電者明確地釋放它:

char *getLine() { 
    char* line = malloc(30); 
    ... 
    return line; 
} 

// somewhere: 
char* line = getLine(); 
... 
free(line); 
+1

我應該製作一個這個答案的模板..;) – KBart 2013-02-14 10:24:39

4

替代不使用malloc,不包括在前面的問題,只要我能找到的:

/* Warning, this function is not re-entrant. It overwrites result of previous call */ 
char *getLine(FILE *input) { 
    static char line[30]; 
    return fgets(line, sizeof(line), input); 
    /* fgets returns NULL on failure, line on success, no need to test it */ 
} 

說明:即使在函數返回後,static variablesfunction scope也保留其值。這個變量只有一個實例,每次調用該函數都會使用同一個變量(因此不能重新進入/線程安全)。程序啓動時爲靜態變量分配內存,既不是堆棧也不是堆棧,但是它在運行程序內存空間時是自己的保留區域。靜態變量的值在第一次使用之前被初始化一次(上面沒有具體的初始化,所以它被填充0,但它也可以有一個初始化器,並且只有當函數被第一次調用時它纔是值)。雖然以這種方式使用靜態變量可能看起來有些不方便(我同意它),但它仍然是標準C所使用的有效模式,例如with strtok() function。它還表明需要一個可重入的版本,因爲C標準也有strtok_r(),因爲它有一個額外的參數,而不是其中的局部靜態變量,所以使用起來更復雜。

相關問題