這日,我寫下如下代碼:
#include <iostream>
int main(void)
{
char *p = new char[5];
char *t = new char[5];
strcpy(t, "Hello");
strcpy(p, t);
std::cout<<p<<std::endl;
delete [] p;
delete [] t;
system("pause");
return 0;
}
看了看,基本沒問題,心想萬事大吉,編譯一下,可問題卻出來了:
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
warning C6211: 由於出現異常,正在泄漏內存“p”。應考慮使用局部 catch 塊清理內存: Lines: 5, 6
warning C6386: 緩沖區溢出: 訪問“參數 1”時,“5*1”個字節可寫,但可能寫入了“6”個字節: Lines: 5, 6, 8
出現4個警告,仔細看看,前2個屬於同一個問題,第3個問題包含2個問題,但也屬於同一類,第4個問題仔細看看,也是和第一個問題一樣,是strcpy的問題;
我納悶,這個怎么會出現問題?看看它的提示,出現緩沖區溢出,再翻翻MSDN,上面這樣寫着:
The strcpy_s function copies the contents in the address of strSource, including the terminating null character, to the location specified by strDestination. The destination string must be large enough to hold the source string, including the terminating null character. The behavior of strcpy_s is undefined if the source and destination strings overlap.
If strDestination or strSource is a null pointer, or if the destination string is too small, the invalid parameter handler is invoked as described in Parameter Validation. If execution is allowed to continue, these functions return EINVAL and set errno to EINVAL.Upon successful execution, the destination string will always be null terminated.
大體瞄了幾眼,大體意思是說strcpy_s會盡顯緩沖區溢出檢測,如果有問題,則拋出一個異常,而strcpy則可能不會拋出異常但會導致程序錯誤,也有可能由於非法訪問而拋出異常。
第4個警告已經說明程序存在緩沖區溢出,所以strcpy會出現異常。
再來看看第3個問題,警告說
char *p = new char[5];
char *t = new char[5];
存在內存泄露,再看看MSDN,上面寫道:
警告 C6211:由於出現異常,正在泄漏內存 <pointer>。應考慮使用局部 catch 塊清理內存,此警告意味着在引發異常時未釋放已分配的內存。位於路徑末尾的語句可能會引發異常。
也就是說,編譯器檢測到程序會泄露內存,所以建議使用try...catch來清理內存。
問題終於搞明白了,於是開始動手,代碼改為如下:
#include <iostream>
int main(void)
{
char *p = NULL;
char *t = NULL;
try
{
p = new char[6];
t = new char[6];
strcpy_s(t, 6, "Hello");
strcpy_s(p, 6, t);
std::cout<<p<<std::endl;
delete [] p;
delete [] t;
}
catch(std::bad_alloc &bad)
{
std::cout<<bad.what()<<std::endl;
if (NULL != p)
{
delete [] p;
}
if (NULL != t)
{
delete [] t;
}
}
system("pause");
return 0;
}
編譯一下,OK,通過,運行,結果正確,問題解決。
http://blog.csdn.net/blpluto/article/details/4515748
