最近參加了很多公司的筆試和面試,經常會遇到這樣一個問題。如下:
[cpp]
char* MyCopy(char *str)
{
char test[1024];
strcpy(test, str);
return test;
}
問題是請你找出這個函數的問題!
存在的疑問點:(我能想到的!大家還有什麼疑點可以留言一起討論)
(1)test這個函數是一個局部變量,在棧上分配的空間再把這個地址返回還能使用嗎?(要點)
(2)還有就是這個str的長度如果超出了1024怎麼辦?
(3)str為空怎麼辦?
下面我就對這三個疑點談談我的看法
疑點1:
首先我們來做個測試
[cpp]
int main(int argc, char *argv[])
{
char *pSource = "Test String";
char *pDest = MyCopy(pSource);
cout<<pDest<<endl;
return 0;
}
結果:
難道這個還能訪問嗎?
那好既然能訪問那我們在把這個測試程序改哈!看哈能不能訪問。
[cpp]
char *pSource = "Test String";
char *pDest = MyCopy(pSource);
<span style="color:#cc0000;">*(pDest + 1) = 'K'; </span>
cout<<pDest<<endl;
結果呢?
耶!難道真的可以使用嗎?
但是我覺得不對啊。我又做了一個測試,定義了另一個函數如下:
[cpp]
void Fill()
{
char test[1024] = "FFFFFFFFFFFFFFFFFFFFFFF";
}
結果盡然是這樣的。到這裡大家應該明白了吧!
下面給出了它的大致內存模型
結論:由於test是個局部變量在函數返回時就已經告訴編譯器0X10000000這個位置的空間是可以再分配給其他的局部變量的但由於我們返回了棧的地址所以我們就可以對他進行修改或者獲取這個地址的數據,但一旦我們定義了其他的局部變量我們剛才的地址空間的數據是可以再分配出去的所以就有可能會覆蓋我們先前的數據,這就是為什麼剛開始時我們能獲取和修改的原因。但是這樣的使用是不安全的因為編譯器沒辦法保證你的這個區域的數據不被覆蓋。我讀到的數據就是”髒數據“。
由於後兩個疑問很好理解在這你我就不再說明了。
有什麼說的不對的地方還望大家多多指點。