strcpy/strncpy/strcpy_s比較

 strcpy()是依據源串的/0作爲結束判斷的,不檢查copy先的Buffer的Size,如果目標空間不夠,就有BufferOverflow問題。請務必使用按照strncpy_s()、strcpy_s()、strncpy()等不同環境而準備的安全度很高的函數。

      strcpy函數,就象gets函數一樣,它沒有方法來保證有效的緩衝區尺寸,所以它只能假定緩衝足夠大來容納要拷貝的字符串。在程序運行時,這將導致不可預料的行爲。
  另外、即使是使用安全度很高的函數,由於用法方面的原因,也可能發生Buffer Overflow,請注意如下幾點。不要在strcpy_s()、strncpy_s()進行Buffer Size的誤指定。

      strcpy_s()兩個參數和三個參數的不同用法區別如下代碼所示:

 

 view plaincopy to clipboardprint?
char *str1=NULL;  
str1=new char[20];  
char str[7];  
strcpy_s(str1,20,"hello world");//三個參數  
strcpy_s(str,"hello");//兩個參數但如果:char *str=new char[7];會出錯:提示不支持兩個參數 
char *str1=NULL;
str1=new char[20];
char str[7];
strcpy_s(str1,20,"hello world");//三個參數
strcpy_s(str,"hello");//兩個參數但如果:char *str=new char[7];會出錯:提示不支持兩個參數

 

       第二個參數表示目標緩衝區大小,大於或等於源串的長度+1(存放結束符/0),strcpy_s必須完全拷貝源串,若只想拷貝一部分源串則應該用strncpy_s函數。


view plaincopy to clipboardprint?
char * dst = (char *)malloc(10);  
//strcpy_s(dst, 10, "Hello world!");  
strncpy(dst, "Hello world!", 10); 
char * dst = (char *)malloc(10);
//strcpy_s(dst, 10, "Hello world!");
strncpy(dst, "Hello world!", 10);

      若使用strncpy不會出錯,觀察內存可以發現,目標指針所指的緩衝區中完全是從源字符串拷貝過來的字符,沒有/0結束符,但是若使用strcpy_s則在運行是出現斷言出錯,所以strncpy仍然不是安全的,因爲有可能出現目標指針的字節數不足存放源指針所指向的內容。另外,若使用語句strncpy(dst, "Hello", 10);則會把剩下的空間都填充爲空字符/0,帶來效率問題,strcpy_s則不會。

     所以從VS2005開始已經推出相應的安全版本——strcpy_s(末尾的s可能代表safe)。

     接口的定義改變如下:

char* strcpy(char* dest, const char* src) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src)

char* strcpy(char* dest, const char* src, size_t count) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src, size_t count)

     後者之所以比前者安全,是因爲他們在接口增加了一個參數numElems來表明dest中的字節數,防止目標指針dest中的空間不夠而導致出現Bug,同時返回值改成返回錯誤代碼,而不是爲了一些所謂的方便而返回char*。這樣接口的定義就比原來安全很多。

 

     更多關於CRT安全性修改的函數參見另一篇文章(轉):VS 2005 CRT函數的安全性增強版本

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/caomiao2006/archive/2009/11/04/4766416.aspx

發佈了76 篇原創文章 · 獲贊 166 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章