2012-07-18 51 views
1

簡單的程序,獲取字符指針並把它放到輸出。垃圾char *放到cout

char * get() 
{ 
    char ss [256]; 
    sprintf (ss,"%d",1); 
    return ss; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char *f = get(); 
    cout<<f; 
    char d[50] ; 
    cin>> d; 
} 

我在輸出中只有垃圾。爲什麼?

+1

可能的重複[可以訪問局部變量的內存超出其範圍?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-範圍) – 2012-07-18 15:55:39

回答

7

函數正在返回局部變量的地址。該代碼具有未定義的行爲,並提供不可預知的結果。

ss駐留在堆棧上,函數get()返回指向它的指針。

char * get() 
{ 
} // Life time of ss ends here 

改爲使用std::string

+1

小調。我使用「指針」而不是「引用」,因爲在C++中,「引用」有其特定的含義。 – 2012-07-18 15:13:28

+0

@DesmondHume同意。 – Mahesh 2012-07-18 15:14:41

+0

@Mahesh請解釋「改爲使用std :: string」。 std :: string不能解決問題,因爲它也可能超出範圍。解決方案的關鍵是使用分配的緩衝區/對象或靜態對象,或讓調用者提供自己的緩衝區。 – Les 2012-07-18 16:46:54

2

當get()函數返回時,局部變量超出範圍。即,它的價值變得不明確。

來解決,可以使用...

static char ss[255]; 
// or 
char *ss = (char *)calloc(1,255); 
// or with C++ 
char *ss = new char[255]; 

或等等...

你決定取捨。使用靜態變量,每次調用get()都可以更改緩衝區的內容。但通過涉及分配的方法,調用者需要釋放內存並知道是使用free()還是delete。一些通過提供緩衝區時調用的功能等處理這個問題......

void get(char *buf, int limit); 
// or 
void get(char *buf, int& limitActual); 

然後最主要的是,與字符串處理時,在C/C++(甚至的std :: string)你正在處理內存必須以某種方式進行管理。使用字符串時,要非常小心自動變量。

+0

如果我做了「calloc」或「new char [255]」,那麼我必須以某種方式在調用者端釋放內存,否則當調用者超出範圍時它將自動完成。 – vico 2012-07-19 14:30:43

+0

'ddd'dd ddd sadsadsadsadsa dsaasd – vico 2012-07-19 17:50:33

+0

糾正我,如果我錯了。如果'void get(char * buf,int&limitActual);'調用者創建變量並設置它的長度。函數'get'填充緩衝區並將limitActual設置爲填充信息長度。 ilimitActual總是> =比由調用者創建的緩衝區長度長。但是誰需要actualLength - 你總能看到零終止字符。 – vico 2012-07-19 17:56:34

2

你的數組ss []只存在於get()的範圍內。
因此,您離開函數後,您從get()返回的指針無效。