2011-03-20 39 views
0

對於一個項目,我必須要求用戶輸入一個文件名,並且我正在使用getchar以字符爲單位讀取它。使用類似代碼時出現奇怪的編譯器投訴

從主,我打電話功能char *coursename= introPrint(); //start off打印使用說明並獲得第一位的輸入。該函數被定義爲

char *introPrint(){ 
    int size= 20; 
    int c; 
    int length=0; 
    char buffer[size]; 


    //instructions printout, cut for brevity 

    //get coursename from user and return it 
    while ((c=getchar()) != EOF && (c != '\n')){ 
    buffer[length++]= c; 
    if (length==size-1) 
     break; 

    } 
    buffer[length]=0; 
    return buffer; 
} 

這基本上是相同的代碼我寫詢問用戶輸入,以星號代替字符回聲,然後打印出結果。在這裏,雖然,我得到了返回聲明的function returns address of local variable警告。那麼,爲什麼我從其他程序沒有收到警告,但爲此代碼觸發了一個警告?

回答

3

您將返回buffer的地址,該地址在超出範圍時(函數返回時)被銷燬。當您嘗試使用返回的指針時,程序的行爲未定義:程序可能會重新使用以前位於buffer實例的內存用於其他目的。

使用一個static緩衝區,用malloc分配一個緩衝區或讓調用者通過一個緩衝區。在最後一種情況下,函數及其調用者也需要以某種方式通知緩衝區的長度(例如,通過額外的參數size)。

+0

有意義。除了製作全局變量之外,還有其他選擇嗎?\ – Jason 2011-03-20 16:07:28

+0

@Jason:更新了我的答案。 – 2011-03-20 16:07:59

+0

是的。分配內存或使用靜態緩衝區。 – ThiefMaster 2011-03-20 16:09:49

1

該警告告訴您,您的函數內有堆棧內存(用於緩衝區對象),因此您不應該從外部訪問它。根據環境情況,用於保存輸入的內存可能會在您想使用時被其他數據覆蓋。

定義分配內存給你的coursename,然後傳遞一個指向你的函數的指針或動態分配緩衝區內存會更好。

1

因爲在這裏,你真的返回指針到本地(該函數的範圍)VAR:
char buffer[size];

所以,函數的執行後,該陣列被破壞,指針是無效的,你會得到未定義的行爲。

爲了解決這個問題,你應該動態分配數組,使用malloc

char* buffer = (char*)malloc(size * sizeof(char));
0

只是你沒在其他功能返回一個指向緩衝區的猜測。

問題是當函數返回時,所有局部變量都被銷燬。這意味着返回的指針不再指向任何地方。沒有緩衝區。不好!

0

當你聲明char buffer []時,它會將該緩衝區放置在堆棧上。當函數退出時,堆棧彈出並且緩衝區停止存在。如果你想返回一個動態緩衝區,在窗口中調用malloc()(或者GlobalAlloc(),或者在C++中使用new操作符)。

static關鍵字將導致緩衝區存在於堆棧之外,基本上與全局相同,只在函數外部不可訪問。

相關問題