這是不安全的。原因很簡單:
函數的任何變量都會分配到函數返回後釋放內存的堆棧上。內存被釋放的事實並不意味着它的內容被改變了。
這意味着你沒有把在變量char buff[20]
存儲器內容仍處於buff
或ptr
(因爲ptr=buff
)內存位置。無論何時調用另一個函數(或執行另一個塊),它的函數/塊變量也將進入堆棧,從而創建更改位置ptr
指向的內存內容的可能性。
在您編寫的strcpy
示例中,您足夠幸運地發現strcpy函數變量沒有進入舊的buff
陣列中的位置。這就是您得到安全的印象。
結論是,你無法真正保證在兩次函數調用之間堆棧的已釋放內存不會改變。
解決方法是使用malloc
,因爲malloc
不會在堆棧上分配內存,而是在堆上分配內存。除非您選擇這樣做(通過免費通話),否則堆內存不會被釋放。
這種方法可以保證ptr
指向的內存可以安全地被任何其他函數使用。
這種解決方案的缺點是內在的:曾經的記憶不釋放,除非你編程方式做到這一點,如果你忘記釋放該內存和失去ptr
的內容,這種記憶會在那裏,分配給你的程序,但從來沒有隻要你的程序運行,就可以實現。該內存將成爲內存泄漏:-)
這就是爲什麼一些語言有垃圾收集一個...但這是另一個故事了:-)
PS:我認爲它是安全的(如果你的程序是單線程的),但我不推薦,做這樣的事情:
{
char safe_buffer[20];
char *unsafe_ptr;
int i;
unsafe_ptr = f1();
/*Copy the buffer without calling any function
not to change the stack content
*/
for(i=0;i<20 && *(unsafe_ptr + i) != 0;i++)
{
*(safe_buffer + i) = *(unsafe_ptr + i);
}
*(safe_buffer + i) = 0;
f2(safe_buffer);
}
來源
2010-02-26 13:04:20
Edu
+1非常多。 – Tom 2010-02-26 12:46:46
它正常工作的原因是在x86上,buff數組從低位地址填充到高位地址,並且可能不會被strcpy的堆棧使用所觸及。不要這樣做:由於信號和中斷等異步事件,堆棧使用可能會有所不同。 – 2010-02-26 12:57:25