2010-09-18 48 views
1

可能重複:
Pointer to local variable警告C4172:返回局部變量的地址或臨時

我已經在這個網站大約同樣的問題看了很多其他主題知道它會是常見的。但我想我是愚蠢的,無法弄清楚正確的做法。所以,我爲這些問題中的另一個道歉,我希望有人能給我一個簡單的解決方案和/或解釋。

這裏是整個代碼:

MAIN.C

#define WIN32_LEAN_AND_MEAN 

#include <Windows.h> 
#include <stdlib.h> 
#include <tchar.h> 


LPTSTR GetApplicationPath (HINSTANCE Instance); 


int APIENTRY _tWinMain (HINSTANCE Instance, HINSTANCE PreviousInstance, LPTSTR CommandLine, int Show) 
{ 
    LPTSTR sMessage = GetApplicationPath (Instance); 

    MessageBox (
     NULL, 
     sMessage, 
     _T ("Caption!"), 
     MB_OK 
    ); 

    return 0; 
} 


LPTSTR GetApplicationPath (HINSTANCE Instance) 
{ 
    _TCHAR sReturn[MAX_PATH]; 

    GetModuleFileName ((HMODULE) Instance, sReturn, MAX_PATH); 

    return sReturn; 
} 

回答

7

現在,你回自動(棧)陣列的地址。這是總是錯誤,因爲只要函數結束,那麼內存的使用壽命也是如此。

您需要使用malloc(和free)或其他動態分配。例如:

_TCHAR *sReturn = malloc(sizeof(_TCHAR) * MAX_PATH); 

我省略了錯誤檢查。然後,調用代碼應該釋放它。之後,在MessageBox_tWinMain

free(sMessage); 
+0

固定,謝謝。顯然,我必須等待9分鐘才能接受,但我會。再次感謝。 :) – 2010-09-18 02:37:39

+0

只需添加一個演員陣容,我相信你和每個人都已經知道這一點,但:_TCHAR * sReturn =(_TCHAR *)malloc(sizeof(_TCHAR)* MAX_PATH); – 2010-09-18 02:39:12

+1

@吉他,你不*需要在C中投射。這可能意味着你真的在使用C++。 – 2010-09-18 02:43:08

1

警告說,這一切。在函數GetApplicationPath中,您返回的函數是本地的sReturn。局部變量在函數返回後不再存在,並且在函數返回之後引用它們是不正確的。

爲了克服這一點,你可以動態SOF sReturn分配空間爲:

sReturn = malloc(sizeof(_TCHAR) * MAX_PATH); 
+3

在C中,'malloc'的返回不應該被轉換。當忘記包含「stdlib.h」時,這可能會在64個arch上丟失你的地址的一小部分...... Casting'malloc'是C++習慣。你需要這樣做,但無論如何你通常應該使用'new'。 – 2010-09-18 06:09:21

2

考慮修改:

LPTSTR GetApplicationPath (HINSTANCE Instance) 

喜歡的東西

void GetApplicationPath (HINSTANCE Instance, LPTSTR str) 

這將消除需要返回一個局部變量。

+0

你可以這樣做,但'GetApplicationPath'應該只帶一個'LPTSTR',因爲你只是寫了一個字符到那個位置,而不是設置調用者的變量。另外,它必須有一個長度參數或文檔,它必須是'MAX_PATH'。 – 2010-09-18 02:41:33

+0

@Matthew - 我解決了你提到的指針問題。謝謝。我想我會把你提到的MAX_PATH問題留給用戶的想象力。這個論點真的可以是他們喜歡的東西(例如char pathname [MAX_PATH])。乾杯 – skimobear 2010-09-18 02:57:53

2

變化

 _TCHAR sReturn[MAX_PATH];
在 「GetApplicationPath」

 static _TCHAR sReturn[MAX_PATH];

如果只有一個線程將被調用GetApplicationPath(),動態地分配這個字符串是矯枉過正。將局部變量標記爲靜態爲全局變量分配空間,以便在退出函數時不會佔用空間。

+0

除非您針對堆棧和堆使用進行了優化,否則這樣做並沒有什麼意義。一般來說,沒有人會優化堆棧使用,並且不推測線程問題更安全。 – 2010-09-18 05:55:57

相關問題